gpt4 book ai didi

c++ - ffmpeg 和 boost::asio NULL 指针

转载 作者:行者123 更新时间:2023-12-04 23:28:54 24 4
gpt4 key购买 nike

我正在尝试制作一个可以在多台核心机器上运行的特殊视频软件。

我想要许多 c++ 对象来流式传输视频文件和许多其他 c++ 对象来将流式数据存储到文件中。

我创建了一些简单的类,但是当我尝试创建 2 个或更多对象时,我得到了:

opening stream9079.sdp
[udp @ 0xaef5380] bind failed: Address already in use
Could not open input file stream9079.sdp
Segmentation fault (core dumped)

当我只使用一个对象时,一切都很好。

我使用以下代码
int main(int argc, char **argv)
{
boost::asio::io_service ios;
boost::asio::io_service ios1;

Channel *channels[100];

channels[0] = new Channel(ios, 9078, atoi(argv[1]));
channels[0]->StartTimer(0);

channels[1] = new Channel(ios1, 9079, atoi(argv[1]));
channels[1]->StartTimer(0);

boost::thread t(boost::bind(&worker, &ios));
boost::thread t1(boost::bind(&worker, &ios1));


t.join();
t1.join();

CEVLOG_MSG << "done" << std::endl;

return 0;
}

我的 Channel类实现是:
#include "channel.hpp"
#include "utils.hpp"
#include "boost/lexical_cast.hpp"
Channel::Channel(boost::asio::io_service &ioP, int i, bool to_send):
Runnable(ioP),
work( new boost::asio::io_service::work(ioP) ),
ofmt(NULL),
ifmt_ctx(NULL),
ofmt_ctx(NULL)
{
id = i;
sender = to_send;

if (sender)
{
input.assign("/home/georgi/Downloads/video/IMG_0019.MOV");
output.assign("rtp://10.101.3.60:"); output += boost::lexical_cast<std::string>(id);
}
else
{
input.assign("stream"); input += boost::lexical_cast<std::string>(id); input += ".sdp";
output.assign("test"); output += boost::lexical_cast<std::string>(id); output += ".mp4";
}

video_idx = audio_idx = sub_idx = -1;

if (OpenInput())
{
if (sender)
OpenOutput(eStreamOutput);
else
OpenOutput(eFileOutput);
}
}

Channel::~Channel()
{
av_write_trailer(ofmt_ctx);

avformat_close_input(&ifmt_ctx);

if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
avio_closep(&ofmt_ctx->pb);

avformat_free_context(ofmt_ctx);

work.reset();
}

bool Channel::OpenInput()
{
CEVLOG_MSG << "opening " << input << std::endl;

int ret;
if ((ret = avformat_open_input(&ifmt_ctx, input.c_str(), 0, 0)) < 0)
{
CEVLOG_ERR << "Could not open input file " << input << std::endl;
return false;
}

CEVLOG_MSG << " " << ifmt_ctx << std::endl;

if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0)
{
CEVLOG_ERR << "Failed to retrieve input stream information" << std::endl;
return false;
}

ifmt_ctx->flags |= AVFMT_FLAG_GENPTS;

//read and set timestamps to 0
av_read_frame(ifmt_ctx, &pkt);
pkt.pts = pkt.dts = 0;

return true;
}

bool Channel::OpenOutput(tOutputType WhatToOpen)
{
int SDP_size;

switch (WhatToOpen)
{
case eFileOutput:
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, output.c_str());
break;

case eStreamOutput:
avformat_alloc_output_context2(&ofmt_ctx, NULL, "rtp", output.c_str());

char SDP[4096];
SDP_size = 4096;

av_sdp_create(&ofmt_ctx, 1, SDP, SDP_size);
CEVLOG_DBG << "SDP=" << SDP << std::endl;
break;

default:
assert(false);
break;
}

if (!ofmt_ctx)
{
CEVLOG_ERR << "Could not create output context" << std::endl;
return false;
}

ofmt = ofmt_ctx->oformat;

video_idx = FindIndex(AVMEDIA_TYPE_VIDEO);

if (!(ofmt->flags & AVFMT_NOFILE))
{
if (avio_open(&ofmt_ctx->pb, output.c_str(), AVIO_FLAG_WRITE) < 0)
{
CEVLOG_ERR << "Could not open output file " << output << std::endl;
return false;
}
}

if (avformat_write_header(ofmt_ctx, NULL) < 0)
{
CEVLOG_ERR << "Error occurred when opening output file " << output << std::endl;
return false;
}

return true;
}

unsigned int Channel::FindIndex(AVMediaType Type)
{
int idx;

for (idx = 0; idx < ifmt_ctx->nb_streams; idx++)
{
if (ifmt_ctx->streams[idx]->codec->codec_type == Type)
{
AVStream *in_stream = ifmt_ctx->streams[idx];
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);

if (!out_stream)
{
CEVLOG_ERR << "Failed allocating output stream" << std::endl;
break;
}

if (avcodec_copy_context(out_stream->codec, in_stream->codec) < 0)
{
CEVLOG_ERR << "Failed to copy context from input to output stream codec context" << std::endl;
break;
}

out_stream->codec->codec_tag = 0;
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
{
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
}

break;
}
}

return idx;
}

void Channel::Callback()
{
if (sender)
SendVideo();
else
RecvVideo();
}

void Channel::SendVideo()
{
int ret = av_read_frame(ifmt_ctx, &pkt);
int time_ms = 0;

if (ret != 0)
{
av_write_trailer(ofmt_ctx);
work.reset();
return;
}

if (pkt.stream_index == video_idx)
{
AVStream *in_stream = ifmt_ctx->streams[pkt.stream_index];
AVStream *out_stream = ofmt_ctx->streams[pkt.stream_index];

AVRational time_base = ifmt_ctx->streams[video_idx]->time_base;

char timestamp[100];
time_ms = 1000 * 1000 * strtof(timestamp2char(timestamp, pkt.duration, &time_base), NULL);

pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF);
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF);
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;

ret = av_interleaved_write_frame(ofmt_ctx, &pkt);

if (ret < 0)
{
CEVLOG_ERR << "Error muxing packet" << std::endl;
return;
}
}

av_free_packet(&pkt);

StartTimer(time_ms);
}

void Channel::RecvVideo()
{
int ret = av_read_frame(ifmt_ctx, &pkt);

if (ret != 0)
{
//Some error or end of stream is detected. Write file trailer
av_write_trailer(ofmt_ctx);
work.reset();
return;
}

//if is NOT video just continue reading
if (pkt.stream_index == video_idx)
{
AVStream *in_stream = ifmt_ctx->streams[pkt.stream_index];
AVStream *out_stream = ofmt_ctx->streams[pkt.stream_index];

AVRational time_base = ifmt_ctx->streams[video_idx]->time_base;

pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF);
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF);
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;

ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
if (ret < 0)
{
CEVLOG_ERR << "Error muxing packet" << std::endl;
return;
}
}

av_free_packet(&pkt);

StartTimer(0);
}

最佳答案

我不知道那些库,但看起来你正在多次抓取端口 9078 和 9079。

关于c++ - ffmpeg 和 boost::asio NULL 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29491307/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com