用一张图表示接下来FFmpeg多线程拉流(橙色框框):
![](https://i-blog.csdnimg.cn/blog_migrate/4b4128f2f4d8ba71972180c0d041fe54.png)
环境是Ubuntu18.04,ffmpeg4.1.5
主要有这么几个文件:
main.cpp
transdata.cpp
transdata.h
源码
主程序main.cpp分为两个部分,一是main()函数里申请pthread线程ID,开启线程,释放线程;二是athread线程函数的编写,每一个用户拉的流根据用户ID而定,比如用户ID为1的,拉流地址后面加1。main.cpp
:
#include <iostream>
#include "transdata.h"
using namespace std;
vector<Transdata> user_tran;
void *athread(void *ptr)
{
int count = 0;
int num = *(int *)ptr;
//初始化
while((user_tran[num].Transdata_init(num))<0)
{
cout << "init error "<< endl;
}
cout <<"My UserId is :"<< num << endl;
//do something you want
user_tran[num].Transdata_Recdata();
user_tran[num].Transdata_free();
return 0;
}
int main(int argc, char** argv)
{
int ret;
//申请内存 相当于注册
for(int i = 0; i < 5 ; i++)
{
Transdata *p = new Transdata();
user_tran.push_back(*p);
user_tran[i].User_ID = i;
cout << &user_tran[i] << endl;
delete p;
}
//开启五个线程
for(int i = 0; i < 5; i ++)
{
int *num_tran;
num_tran = &user_tran[i].User_ID;
ret = pthread_create(&user_tran[i].thread_id,NULL,athread,(void *)num_tran);
if(ret < 0) return -1;
}
for(int i = 0; i < 5; i++)
{
pthread_join(user_tran[i].thread_id, NULL);/*等待进程t_a结束*/
}
return 0;
}
transdata.cpp transdata.h是拉流的功能函数。
transdata.cpp
:
#include "transdata.h"
Transdata::Transdata(){}
Transdata::~Transdata(){}
int Transdata::Transdata_free()
{
av_bsf_free(&bsf_ctx);
avformat_close_input(&ifmt_ctx);
av_frame_free(&pframe);
if (ret < 0 && ret != AVERROR_EOF)
{
printf( "Error occurred.\n");
return -1;
}
return 0;
}
int Transdata::Transdata_Recdata()
{
//可以自己增加LOG函数
//LOGD("Transdata_Recdata entry %d",User_ID);
int count = 0;
while(av_read_frame(ifmt_ctx, &pkt)>=0)
{
//LOGD("av_read_frame test %d",User_ID);
if (pkt.stream_index == videoindex) {
// H.264 Filter
if (av_bsf_send_packet(bsf_ctx, &pkt) < 0){
cout << " bsg_