|
|
|
@ -25,6 +25,7 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) {
|
|
|
|
|
qDebug() << "Could not create output context.";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制流信息
|
|
|
|
|
for (unsigned int i = 0; i < inputFormatCtx->nb_streams; ++i) {
|
|
|
|
|
// AVStream *stream = inputFormatCtx->streams[i];
|
|
|
|
@ -47,6 +48,24 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) {
|
|
|
|
|
// outputStream->codecpar = inputStream->codecpar;
|
|
|
|
|
outputStream->codecpar->codec_tag = 0;
|
|
|
|
|
// outputStream->time_base.num = 1;
|
|
|
|
|
|
|
|
|
|
// if (outputFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
|
|
|
|
|
// c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
|
|
|
|
|
|
|
|
|
// if (outputFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) {
|
|
|
|
|
// outputFormatCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
|
|
|
|
// if (inputStream->codecpar->extradata_size > 0) {
|
|
|
|
|
// int extra_size = (uint64_t)inputStream->codecpar->extradata_size +
|
|
|
|
|
// AV_INPUT_BUFFER_PADDING_SIZE;
|
|
|
|
|
// outputStream->codecpar->extradata = (uint8_t
|
|
|
|
|
// *)av_malloc(extra_size); memcpy(outputStream->codecpar->extradata,
|
|
|
|
|
// inputStream->codecpar->extradata,
|
|
|
|
|
// inputStream->codecpar->extradata_size);
|
|
|
|
|
// outputStream->codecpar->extradata_size =
|
|
|
|
|
// inputStream->codecpar->extradata_size;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -66,6 +85,7 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) {
|
|
|
|
|
qDebug() << "Error occurred when write_header into output file.\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
// sendSPS_PPS(inputFormatCtx, outputFormatCtx);
|
|
|
|
|
mInitStatus = true;
|
|
|
|
|
this->inputFormatCtx = inputFormatCtx;
|
|
|
|
|
// startTime = av_gettime_relative();
|
|
|
|
@ -96,6 +116,64 @@ int FFmpegPushStream::reconnect(int ret) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int FFmpegPushStream::sendSPS_PPS(AVFormatContext *input_format_context,
|
|
|
|
|
AVFormatContext *output_format_context) {
|
|
|
|
|
for (unsigned int i = 0; i < input_format_context->nb_streams; i++) {
|
|
|
|
|
AVStream *in_stream = input_format_context->streams[i];
|
|
|
|
|
|
|
|
|
|
if (in_stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
|
|
|
|
AVStream *out_stream = output_format_context->streams[0];
|
|
|
|
|
// Send SPS and PPS for video
|
|
|
|
|
AVCodecContext *codec_context = avcodec_alloc_context3(nullptr);
|
|
|
|
|
if (!codec_context) {
|
|
|
|
|
qDebug() << "Could not allocate video codec context.";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (avcodec_parameters_to_context(codec_context, in_stream->codecpar) <
|
|
|
|
|
0) {
|
|
|
|
|
qDebug() << "Failed to copy codec parameters to context.";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AVPacket sps_pps_packet;
|
|
|
|
|
av_init_packet(&sps_pps_packet);
|
|
|
|
|
sps_pps_packet.data = nullptr;
|
|
|
|
|
sps_pps_packet.size = 0;
|
|
|
|
|
|
|
|
|
|
if (avcodec_send_frame(codec_context, nullptr) < 0) {
|
|
|
|
|
qDebug() << "Failed to send a frame for SPS/PPS extraction.";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (avcodec_receive_packet(codec_context, &sps_pps_packet) == 0) {
|
|
|
|
|
if (sps_pps_packet.pts == AV_NOPTS_VALUE) {
|
|
|
|
|
sps_pps_packet.pts =
|
|
|
|
|
av_rescale_q_rnd(sps_pps_packet.dts, codec_context->time_base,
|
|
|
|
|
out_stream->time_base, AV_ROUND_NEAR_INF);
|
|
|
|
|
}
|
|
|
|
|
sps_pps_packet.dts =
|
|
|
|
|
av_rescale_q_rnd(sps_pps_packet.dts, codec_context->time_base,
|
|
|
|
|
out_stream->time_base, AV_ROUND_NEAR_INF);
|
|
|
|
|
sps_pps_packet.duration =
|
|
|
|
|
av_rescale_q(sps_pps_packet.duration, codec_context->time_base,
|
|
|
|
|
out_stream->time_base);
|
|
|
|
|
sps_pps_packet.pos = -1;
|
|
|
|
|
sps_pps_packet.stream_index = out_stream->index;
|
|
|
|
|
|
|
|
|
|
if (av_interleaved_write_frame(output_format_context, &sps_pps_packet) <
|
|
|
|
|
0) {
|
|
|
|
|
qDebug() << "Error sending SPS/PPS packet.";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
av_packet_unref(&sps_pps_packet);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
avcodec_free_context(&codec_context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 推流
|
|
|
|
|
* @param pkt: 未解码帧
|
|
|
|
@ -149,7 +227,7 @@ int FFmpegPushStream::pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime,
|
|
|
|
|
// qDebug() << "****************PushStream sleep time:"
|
|
|
|
|
// << QString::number(delay / 1000);
|
|
|
|
|
av_usleep(delay);
|
|
|
|
|
// sleepMsec(delay);
|
|
|
|
|
// sleepMsec(40);
|
|
|
|
|
} else {
|
|
|
|
|
// av_packet_unref(pkt);
|
|
|
|
|
// return 1;
|
|
|
|
@ -181,7 +259,7 @@ int FFmpegPushStream::pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime,
|
|
|
|
|
int ret = av_interleaved_write_frame(outputFormatCtx, pkt);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
if (ret == -10053) {
|
|
|
|
|
qDebug() << "网络不稳定";
|
|
|
|
|
// qDebug() << "网络不稳定";
|
|
|
|
|
}
|
|
|
|
|
// if (ret == AVERROR(EPIPE) || ret == AVERROR(ECONNRESET)) {
|
|
|
|
|
// qDebug() << "网络不稳定1";
|
|
|
|
|