ZBLOG

ffmpeg4.2.1

如果你想在 FFmpeg 4.2.1 中使用 C++ 解码 H.264 摄像头数据,可以参考以下的示例代码。这个示例展示了如何打开摄像头流,读取视频帧并解码。

确保你已安装 FFmpeg,并且在编译时正确链接相关库 (libavformat, libavcodec, libavutil, libswscale)。

示例代码

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

#include <iostream>

int main() {
    // 注册所有组件
    av_register_all();

    // 打开摄像头设备(根据你的系统可能需要更改)
    const char* deviceName = "/dev/video0";  // Linux 的设备名
    AVFormatContext* pFormatCtx = nullptr;

    if (avformat_open_input(&pFormatCtx, deviceName, nullptr, nullptr) != 0) {
        std::cerr << "Couldn't open input stream." << std::endl;
        return -1;
    }

    // 查找流信息
    if (avformat_find_stream_info(pFormatCtx, nullptr) < 0) {
        std::cerr << "Couldn't find stream info." << std::endl;
        avformat_close_input(&pFormatCtx);
        return -1;
    }

    int videoStreamIndex = -1;

    for (unsigned int i = 0; i < pFormatCtx->nb_streams; ++i) {
        if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }

    if (videoStreamIndex == -1) {
        std::cerr << "Couldn't find a video stream." << std::endl;
        avformat_close_input(&pFormatCtx);
        return -1;
    }

    AVCodecParameters* pCodecParameters = pFormatCtx->streams[videoStreamIndex]->codecpar;

    // 查找解码器
    AVCodec* pCodec = avcodec_find_decoder(pCodecParameters->codec_id);
    
    if (!pCodec) {
        std::cerr << "Unsupported codec!" << std::endl;
        avformat_close_input(&pFormatCtx);
        return -1;
    }

  	// 创建解码上下文
  	AVCodecContext* pCodecCtx = avcodec_alloc_context3(pCodec);  

  	if (!pCodecCtx) {  
      	std::cerr << "Could not allocate codec context." << std::endl;  
      	avformat_close_input(&pFormatCtx);  
      	return -1;  
  	}  

  	// 初始化解码上下文参数
  	if (avcodec_parameters_to_context(pCodecCtx, pCodecParameters) < 0) {  
      	std::cerr << "Failed to copy codec parameters to decoder context." << std::endl;  
      	avcodec_free_context(&pCodecCtx);  
      	avformat_close_input(&pFormatCtx);  
      	return -1;  
  	}  

  	if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0){   
     	std::cerr<<"Could not open codec!"<<std::endl;   
    	av_codec_free_context (&p_codec_ctx);   
    	av_format_close_input (&fmt_ctx);   
    	return-1; 
  	}

  	AVPacket packet; 
  	AVFrame *frame= av_frame_alloc(); 

	while(av_read_frame(pFormatCtx,&packet)>=0){ 
	  if(packet.stream_index==videoStreamIndex){ 
        	int response= av_codec_send_packet(pCodecCtx,&packet);  
        	if(response<0){ 
            	std :: cerr<<"Error while sending a packet"<<std :: endl; 
            	break ;   
        	}  

        	while(response==0){      
          	response= av_codec_receive_frame(pCodecCtx, frame);         
          	if(response==AVERROR(EAGAIN)||response==AVERROR_EOF){     
              	break ;  
          	} else if(response<0){     
              	std :: cerr<<"Error while receiving a frame"<<std :: endl;      
              	break ;   
          	}        
         	
         	  // 在这里处理每一帧,例如保存、显示等           
          	std :: cout<<"Frame received!"<<std :: endl;  
          } 
      }  

      av_packet_unref(&packet);  
  	}  

  	// 清理资源
  	av_frame_free(&frame);  
  	av_packet_unref(&packet);  
  	avcodec_free_context(&pCodecCtx);  
  	avformat_close_input(&pFormatCtx);

	return 0;

}

编译指令

将上述代码保存为 camera_capture.cpp 文件,然后使用以下命令进行编译:

g++ camera_capture.cpp -o camera_capture -lavformat -lavcodec -lavutil -lswscale

注意事项

  • 设备路径:确保修改设备名称 /dev/video0 为适合你系统的值。
  • 权限问题:运行此程序时,确保具有对摄像头设备的访问权限。
  • 错误处理:实际应用中建议增加更多错误检查与处理逻辑以避免崩溃。
  • FFmpeg版本兼容性:该代码应兼容于 FFmpeg 4.2.1,但某些 API 调用和结构可能会随着版本变化而有所不同。请参考官方文档了解具体细节。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=6797

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?