[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