[Libav-user] saving MMS streams ends up with crashes or breaks before writing
Georg Stein
georg_stein at t-online.de
Sat Apr 4 07:02:05 CEST 2015
Hello,
i made a small app aht connets to internet livestreams and saves them to
disc. This is working fine for hls and http streams but fails on most of
the mms/mmsh/mmst streams. Here i get often a segfault or the app
crashes with the following message:
This application has requested the Runtime to terminate it in an unusual
way.
Please contact the application's support team for more information.
Could not alloc memory for stream options.
[asf @ 06a610a0] Using AVStream.codec.time_base as a timebase hint to
the muxer is deprecated. Set AVStream.time_base instead.
[asf @ 06a610a0] Using AVStream.codec.time_base as a timebase hint to
the muxer is deprecated. Set AVStream.time_base instead.
Assertion asf->packet_timestamp_end >= asf->packet_timestamp_start
failed at libavformat/asfenc.c:746
samle url: mmst://80.246.121.90/ctv
i localized the problem where i open the outputstream and copy the codec
from the input stream:
üerhaps someboday sees here directly what i'm doing wrong, finally i
want to write the instream without decoding/demuxing to disc
AVOutputFormat* fmt = NULL;
if (!this->isRtmp && !this->isRtpMMS) {
fmt =
av_guess_format("mpegts",NULL,/*guessFileNameStd.c_str()*/NULL);
} else {
if (this->isRtpMMS) {
fmt = av_guess_format(NULL, fileNameStd.c_str(), NULL);
} else {
fmt =
av_guess_format("flv",NULL,/*guessFileNameStd.c_str()*/NULL);
}
}
AVFormatContext* oc = avformat_alloc_context();
AVDictionary *avoption = NULL;
oc->oformat = fmt;
// int err = avformat_find_stream_info(this->avFormatContext, NULL);
if (this->authKeyProvider == 6 || this->authKeyProvider == 8) {
av_dict_set(&avoption, "timeout", "15000000",
AV_DICT_APPEND);//15sec timeout
}
avio_open2(&oc->pb, fileNameStd.c_str(), AVIO_FLAG_WRITE, NULL,
&avoption);
/* Some formats want stream headers to be separate. */
// if (this->authKeyProvider == 6 || this->authKeyProvider == 8) {
// oc->flags |= CODEC_FLAG_GLOBAL_HEADER;
// }
AVStream *streamAudio = NULL;
AVStream *streamVideo = NULL;
int cnt = 0;
AVPacket packet = {0};
av_read_play(this->avFormatContext);
int codecCopyOK = -1;
if (this->isRtpMMS) {
if (this->codecCtxAudio != NULL) {
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
this->codecCtxAudio->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
}
if (this->codecCtxVideo != NULL) {
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
this->codecCtxVideo->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
}
AVCodec *out_vid_codec,*out_aud_codec;
out_vid_codec = out_aud_codec = NULL;
if (this->videoStreamIndex > -1) {
// if(fmt->video_codec != AV_CODEC_ID_NONE &&
this->avFormatContext->streams[this->videoStreamIndex] != NULL) {
// out_vid_codec = avcodec_find_encoder(fmt->video_codec);
// if (out_vid_codec == NULL) {
// qDebug() << "could not find video encoder";
// } else {
// streamVideo = avformat_new_stream(oc, out_vid_codec);
// if (streamVideo == NULL) {
// qDebug() << "could not get out video stream";
// } else {
// if(avcodec_copy_context(streamVideo->codec,
this->avFormatContext->streams[this->videoStreamIndex]->codec) != 0) {
// qDebug() << "failed to copy codec context";
// } else {
// streamVideo->sample_aspect_ratio.den =
this->avFormatContext->streams[this->videoStreamIndex]->codec->sample_aspect_ratio.den;
// streamVideo->sample_aspect_ratio.num =
this->avFormatContext->streams[this->videoStreamIndex]->codec->sample_aspect_ratio.num;
// streamVideo->codec->codec_id =
this->avFormatContext->streams[this->videoStreamIndex]->codec->codec_id;
// streamVideo->codec->time_base.num = 1;
// streamVideo->codec->time_base.den =
29*(this->avFormatContext->streams[this->videoStreamIndex]->codec->ticks_per_frame);
// streamVideo->time_base.num = 1;
// streamVideo->time_base.den = 1000;
// streamVideo->r_frame_rate.num = 29;/*fps*/
// streamVideo->r_frame_rate.den = 1;
// streamVideo->avg_frame_rate.den = 1;
// streamVideo->avg_frame_rate.num = 29;/*fps*/
//// streamVideo->duration = (m_out_end_time
- m_out_start_time)*1000;
// }
// }
// }
// }
streamVideo = avformat_new_stream(oc,
/*(AVCodec*)this->codecCtxVideo->codec*/NULL);
codecCopyOK = avcodec_copy_context(streamVideo->codec,
this->codecCtxVideo);
if (oc->video_codec_id == AV_CODEC_ID_NONE) {
oc->video_codec_id = this->codecCtxVideo->codec_id;
oc->bit_rate = this->codecCtxVideo->bit_rate;
oc->flags = this->codecCtxVideo->flags;
}
}
if (this->audioStreamIndex > -1) {
// if(fmt->audio_codec != AV_CODEC_ID_NONE &&
this->avFormatContext->streams[this->audioStreamIndex] != NULL) {
// out_aud_codec = avcodec_find_encoder(fmt->audio_codec);
// if (out_aud_codec == NULL) {
// qDebug() << "could not find audio encoder";
// } else {
// streamAudio = avformat_new_stream(oc,
NULL/*out_aud_codec*/);
// if (streamAudio == NULL) {
// qDebug() << "could not get out audio stream";
// } else {
// AVCodecContext *aCodec = this->codecCtxAudio;
// if(avcodec_copy_context(streamAudio->codec,
aCodec) != 0) {
// qDebug() << "failed to copy codec context";
// } else {
// streamAudio->codec->codec_id =
this->avFormatContext->streams[this->audioStreamIndex]->codec->codec_id;
// streamAudio->codec->codec_tag = 0;
// streamAudio->pts =
this->avFormatContext->streams[this->audioStreamIndex]->pts;
// streamAudio->duration =
this->avFormatContext->streams[this->audioStreamIndex]->duration;
// streamAudio->time_base.num =
this->avFormatContext->streams[this->audioStreamIndex]->time_base.num;
// streamAudio->time_base.den =
this->avFormatContext->streams[this->audioStreamIndex]->time_base.den;
// }
// }
// }
}
streamAudio = avformat_new_stream(oc,
/*(AVCodec*)this->codecCtxAudio->codec*/NULL);
codecCopyOK = avcodec_copy_context(streamAudio->codec,
this->avFormatContext->streams[this->audioStreamIndex]->codec);
if (oc->audio_codec_id == AV_CODEC_ID_NONE) {
oc->audio_codec_id = this->codecCtxAudio->codec_id;
oc->flags = this->codecCtxAudio->flags;
oc->bit_rate = this->codecCtxAudio->bit_rate;
}
// }
} else {
if (this->videoStreamIndex > -1) {
streamVideo = avformat_new_stream(oc,
(AVCodec*)this->codecCtxVideo->codec);
codecCopyOK = avcodec_copy_context(streamVideo->codec,
this->codecCtxVideo);
if (oc->video_codec_id == AV_CODEC_ID_NONE) {
oc->video_codec_id = this->codecCtxVideo->codec_id;
oc->bit_rate = this->codecCtxVideo->bit_rate;
oc->flags = this->codecCtxVideo->flags;
}
}
if (this->audioStreamIndex > -1) {
streamAudio = avformat_new_stream(oc,
(AVCodec*)this->codecCtxAudio->codec);
codecCopyOK = avcodec_copy_context(streamAudio->codec,
this->codecCtxAudio);
if (oc->audio_codec_id == AV_CODEC_ID_NONE) {
oc->audio_codec_id = this->codecCtxAudio->codec_id;
oc->flags = this->codecCtxAudio->flags;
oc->bit_rate = this->codecCtxAudio->bit_rate;
}
}
}
AVDictionary **opts = NULL;
int headerWritten = avformat_write_header(oc, opts);
if (headerWritten < 0) {
this->stopArc = true;
emit this->sigDwnStatus(0, -10);//error
qDebug("emit this->sigDwnStatus stoppedByError redNextFrame 1");
return false;
}
uint64_t actMilliSec = 0;
uint64_t startMsec = 0;
uint64_t msecsGone = 0;
uint64_t video_pts = 0;
qlonglong videoFrameCount = 0;
bool fixPtsDts = false;
if (this->useCorrectTimeStamps) {
fixPtsDts = true;
}
int pts = 0;
int dts = 0;
int size = 0;
qlonglong timeBase = -1;
AVRational tbRat;
if (streamVideo != NULL) {
tbRat = streamVideo->time_base;
timeBase = tbRat.num;
}
AVBitStreamFilterContext *bsfcVideo = NULL;
AVBitStreamFilterContext *bsfcAudio = NULL;
AVPacket new_pkt = {0};
AVCodecContext *avctx = NULL;
int emptyPacketCount = 0;
bool stoppedByError = false;
qlonglong nullPoint = 0;
qlonglong packetCounter = 0;
int fps = 30;
qlonglong actMSecs = 0;
av_init_packet(&packet);
int lifeTimeSig = 3000;
int nullPackets = 0;
bool eof = false;
while(!eof && this->avFormatContext != NULL &&
(this->nrOfDumpFrames == -1 || cnt < this->nrOfDumpFrames) &&
!this->stopArc){
.....
loop where i write the frames
More information about the Libav-user
mailing list