简体   繁体   中英

Saving frames from a network camera (RTSP) to a mp4 file

I am quite confused about how to save a video stream into a mp4 file. I am using ffmpeg. Let me explain the problem:

  1. I connect to a network camera via RTSP (H.264 stream) with avformat_open_input(), avformat_find_stream_info(), av_read_play(), and I get frames with av_read_frame().
  2. Each time I get a frame with av_read_frame(), I store the corresponding AVPacket in a circular buffer.
  3. In some points in my application, a range of this circular buffer is selected. I find a key frame used to start from.
  4. Once I have a list of AVPacket's starting from a key frame, I write header, frames, and tail, as I described below in the code.

The problem is that the resulting mp4 video has artifacts if I try to watch it using VLC, Windows Media Player, or another one.

I have also realized that the pts of that packets are not continuous, while dts are continuous. I know about B frames, but is this a problem in my case?

// Prepare the output
AVFormatContext* oc = avformat_alloc_context();
oc->oformat = av_guess_format(NULL, "video.mp4", NULL);

// Must write header, packets, and trailing
avio_open2(&oc->pb, "video.mp4", AVIO_FLAG_WRITE, NULL, NULL);

// Write header
AVStream* stream = avformat_new_stream(oc, (AVCodec*) context->streams[video_stream_index]->codec->codec);
avcodec_copy_context(stream->codec, context->streams[video_stream_index]->codec);
stream->sample_aspect_ratio = context->streams[video_stream_index]->codec->sample_aspect_ratio;
avformat_write_header(oc, NULL);

// FOR EACH FRAME...
... av_write_frame(oc, circular[k]); ...

// Write trailer and close the file
av_write_trailer(oc);
avcodec_close(stream->codec);
avio_close(oc->pb);
avformat_free_context(oc);

Thank you so much,

First: when you work with the camera, it is better to work through an RTP over TCP (TCP as transport protocol). To enable this feature:

AVDictionary *ifmtdict;
av_dict_set(&ifmtdict, "rtsp_transport", "tcp", 0);
...
avformat_open_input (..., &ifmtdict);

Second: After the packets start coming, wait for the first keyframe and start to write to the file from this moment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM