您好,我正在使用ffmpeg 3.4.2记录来自IP摄像机的RTSP h264蒸汽。我有一个有效的示例,但是开始时我看到一些损坏的图像,几秒钟后,视频可以正确显示。我想知道这是否是时间问题。
说明打开和读取RTSP流并将其写入MP4容器的源代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <sys/time.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libswscale/swscale.h>
}
time_t get_time()
{
struct timeval tv;
gettimeofday( &tv, NULL );
return tv.tv_sec;
}
int main(int argc, char **argv)
{
const char *filename, *codec_name;
const AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y;
// Open the initial context variables that are needed
AVFormatContext* format_ctx = avformat_alloc_context();
int video_stream_index;
// Register everything
av_register_all();
avformat_network_init();
//open RTSP
AVDictionary *ifmtdict;
av_dict_set(&ifmtdict, "rtsp_transport", "tcp", 0);
if (avformat_open_input(&format_ctx, "rtsp://192.168.0.84/user=admin_password=_channel=1_stream=0.sdp",
NULL, &ifmtdict) != 0) {
return EXIT_FAILURE;
}
if (avformat_find_stream_info(format_ctx, NULL) < 0) {
return EXIT_FAILURE;
}
//search video stream
for (int i = 0; i < format_ctx->nb_streams; i++) {
if (format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
video_stream_index = i;
}
AVPacket packet;
av_init_packet(&packet);
AVStream* stream = NULL;
int cnt = 0;
//start reading packets from stream and write them to file
av_read_play(format_ctx); //play RTSP
// Get the codec
codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec) {
exit(1);
}
// Prepare the output
AVFormatContext* oc = avformat_alloc_context();
oc->oformat = av_guess_format(NULL, "video.mp4", NULL);
avio_open2(&oc->pb, "video.mp4", AVIO_FLAG_WRITE, NULL, NULL);
// Write header
stream = avformat_new_stream(oc, (AVCodec*) format_ctx->streams[video_stream_index]->codec->codec);
avcodec_parameters_copy(stream->codecpar, format_ctx->streams[video_stream_index]->codecpar);
stream->sample_aspect_ratio = format_ctx->streams[video_stream_index]->codec->sample_aspect_ratio;
stream->codecpar->codec_tag = 0;
stream->time_base = format_ctx->streams[video_stream_index]->time_base;
avformat_write_header(oc, NULL);
time_t timenow, timestart;
timestart = timenow = get_time();
bool got_key_frame = 0;
while (av_read_frame(format_ctx, &packet) >= 0 && cnt < 200000) { //read ~ 200000 frames
if (packet.stream_index == video_stream_index) { //packet is video
// Make sure we start on a key frame
if ( !got_key_frame && timestart == timenow && ! ( packet.flags & AV_PKT_FLAG_KEY ) ) {
timestart = timenow = get_time();
continue;
}
got_key_frame = 1;
std::cout << cnt << std::endl;
av_interleaved_write_frame( oc, &packet );
cnt++;
}
av_free_packet(&packet);
av_init_packet(&packet);
timenow = get_time();
}
av_write_trailer(oc);
avcodec_close(stream->codec);
avio_close(oc->pb);
avformat_free_context(oc);
av_read_pause(format_ctx);
avcodec_free_context(&c);
avformat_network_deinit();
return 0;
}
答案 0 :(得分:0)
H.264流由帧组(GOP)组成。通常,您只能在GOP边界开始解码。在将视频数据包传递到MP4刻录机之前,您可能必须等待IDR帧。