千家信息网

FFmpeg如何获取网络摄像头数据解码

发表于:2024-11-17 作者:千家信息网编辑
千家信息网最后更新 2024年11月17日,这篇文章主要介绍了FFmpeg如何获取网络摄像头数据解码,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。对USB摄像头实时编码,在前面已
千家信息网最后更新 2024年11月17日FFmpeg如何获取网络摄像头数据解码

这篇文章主要介绍了FFmpeg如何获取网络摄像头数据解码,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

对USB摄像头实时编码,在前面已经探讨过了。这次改变下思路,尝试去截取网络摄像头的H264码流,将其解码播放。

这里的测试代码,是在海康摄像头的基础上进行的。

解码的大致流程和以前的保持一致,只不过增加了部分函数。

FFmpeg打开媒体文件并查看媒体文件的信息,有三个步骤:

avformat_open_input;

avformat_find_stream_info;

av_dump_format;

依次调用三个函数后,我们可以很清楚的知道码流的各种信息。

完整的代码:

#include #include #include #include #include #include "queue.h" extern "C"{#include #include #include } #pragma comment(lib, "avcodec.lib")#pragma comment(lib, "avformat.lib")#pragma comment(lib, "avutil.lib") #pragma comment(lib ,"swscale.lib") using namespace std;using namespace cv; DWORD WINAPI opencv_imshow(LPVOID lparam){ result_link_type* result_link = (result_link_type*)lparam; struct result_node_datatype *result_node2 = NULL; while (1) { result_node2 = result_pop(result_link); if (result_node2 == NULL) { Sleep(1); continue; } imshow("frame", result_node2->result); waitKey(1); }} int main(int argc, const char * argv[]){ HANDLE thread1; result_link_type *result_link = new result_link_type; result_link->head = result_link->end = NULL; result_link->result_num = 0; thread1 = CreateThread(NULL, 0, opencv_imshow, (LPVOID)result_link, 0, NULL); int i; int videoStream; int frameFinished; int numBytes; int ret; int got_picture; long prepts = 0; bool first_time = true; AVCodec *pCodec; AVFrame *pFrame; AVFrame *pFrameRGB; AVPacket packet; AVCodecContext *pCodecCtx; AVFormatContext *pFormatCtx = NULL;//结构体AVFormatContext:包含码流参数较多 static struct SwsContext *img_convert_ctx; uint8_t *buffer; Mat pCvMat; char filepath[] = "rtsp://admin:jdh223456@10.170.6.187/axis-media/media.amp?camera=2";//码流的获取路径 av_register_all();//注册编解码器 avformat_network_init();//加载socket库以及网络加密协议相关的库 if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0)//打开多媒体数据并且获得信息 { return -1; } if (avformat_find_stream_info(pFormatCtx, NULL) < 0)//读取视音频数据并且获得信息 { return -1; } av_dump_format(pFormatCtx, 0, argv[1], false);//手工调试函数,看到pFormatCtx->streams的内容 videoStream = -1; for (i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoStream = i; break; } } if (videoStream == -1) { return -1; } pCodecCtx = pFormatCtx->streams[videoStream]->codec; pCodec = avcodec_find_decoder(pCodecCtx->codec_id);//查找解码器 if (pCodec == NULL) { return -1; } if (avcodec_open2(pCodecCtx, pCodec, 0) < 0)//初始化AVCodecContext { return -1; } if (pCodecCtx->time_base.num > 1000 && pCodecCtx->time_base.den == 1) { pCodecCtx->time_base.den = 1000; } pFrame = av_frame_alloc();//分配内存 pFrameRGB = av_frame_alloc(); i = 0; while (1) { if (av_read_frame(pFormatCtx, &packet) >= 0)//读取码流中的音频若干帧或者视频一帧 { if (packet.stream_index == videoStream) { ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);//开始解码 if (ret < 0) { printf("Decode Error.(解码错误)\n"); return ret; } if (got_picture)//解码成功,got_picture返回任意非零值 { if (first_time) { //初始化SwsContext img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL); if (img_convert_ctx == NULL) { fprintf(stderr, "Cannot initialize the conversion context!\n"); exit(1); } numBytes = avpicture_get_size(AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); buffer = (uint8_t *)av_malloc(numBytes); avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); // allocator memory for BGR buffer pCvMat.create(cv::Size(pCodecCtx->width, pCodecCtx->height), CV_8UC3); first_time = false; } //处理图像数据 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); memcpy(pCvMat.data, buffer, numBytes); struct result_node_datatype *result_node = new struct result_node_datatype; result_node->result = pCvMat; result_push(result_link, result_node); } } av_free_packet(&packet); } } //free(buffer); av_free(buffer); av_free(pFrameRGB); av_free(pFrame); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); system("Pause"); return 0;}

队列函数:

#include "queue.h"#include using namespace std; void result_push(result_link_type* result_link, result_node_datatype * result_node) //入队操作{ if (result_link->head == NULL) { result_link->head = result_node; result_link->end = result_link->head; result_link->result_num++; } else { result_link->end->next = result_node; result_link->end = result_node; result_link->result_num++; }} struct result_node_datatype* result_pop(result_link_type* result_link) //出队操作{ struct result_node_datatype* tmp_node; if (result_link->head == NULL) return NULL; else if (result_link->head == result_link->end) { return NULL; } else { tmp_node = result_link->head; result_link->head = result_link->head->next; result_link->result_num--; return tmp_node; }}

队列函数的头文件:

#ifndef QUEUE_H#define QUEUE_H#include #include #include #include using namespace cv; typedef struct result_link_datatype{ struct result_node_datatype *head; struct result_node_datatype *end; int result_num;}result_link_type; struct result_node_datatype{ Mat result; struct result_node_datatype* next;}; void result_push(result_link_type* result_link, result_node_datatype * result_node); //入队操作struct result_node_datatype* result_pop(result_link_type* result_link);//出队操作 #endif

解码后的数据进入队列,再从队列中取出,利用opencv将其显示(opencv显示是另外开的一个线程函数)。

admin:jdh223456@10.170.6.187,这里是摄像头的名称和IP地址。

感谢你能够认真阅读完这篇文章,希望小编分享的"FFmpeg如何获取网络摄像头数据解码"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

摄像头 摄像 数据 函数 网络 篇文章 队列 信息 文件 三个 代码 媒体 媒体文件 解码器 清楚 一致 价值 兴趣 内存 参数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 剑侠世界服务器数字 纯真 ip 数据库 君临天下是哪个服务器的 互联网通信科技设计 国家网络安全知识视频 网络安全要不要读博 山东盈实互联网络科技可信 宝安区数据网络技术开发分类 大数据和网络安全哪个专业好就业 虹口区品牌软件开发卖价 杭州启强游戏app软件开发定制 大众迈腾导航数据库 软件开发给了定金没有合同 怎么用本地数据库 提升DNS服务器安全的方法有 深圳蓝鲸网络技术 菏泽软件开发小公司电话 伊春gpu服务器 国家网络安全信息化座谈会 贵州信息安全学习网络安全 数据库表字段名怎么看 浙江综合软件开发销售电话 艾尔登法环 连接服务器 闪退 网络安全审查要素 绿森林网络技术公司 软件开发知识产权怎么写 校园网络安全处置应急预案 民族企业服务器 服务器为什么不能连接光猫 网络安全测评公司是科技型公司吗
0