#include"check_tool.h" extern "C" { #include #include #include #include #include #include #include #include } #include static long long get_cur_time(){ // 获取操作系统当前时间点(精确到微秒) chrono::time_point tpMicro = chrono::time_point_cast(chrono::system_clock::now()); // (微秒精度的)时间点 => (微秒精度的)时间戳 time_t currentTime = tpMicro.time_since_epoch().count(); return (long long )currentTime; } void save_pkt(const string& uri){ AVFormatContext* ifmt_ctx = nullptr; AVCodecContext* codec_ctx = nullptr; AVCodec *decoder = nullptr; AVCodec* codec = nullptr; AVPacket* pkt = nullptr; int video_index = -1; AVStream* i_video_stream = nullptr; SwsContext *img_convert_ctx = nullptr; uint8_t *buffer = nullptr; int numBytes = 0; long start_time = 0; long end_time = 0; long s_time = 0; long e_time = 0; long long sum = 0; double avg_time = 0.0; int sep = 0; AVFormatContext *o_fmt_ctx; AVStream *o_video_stream; const char *filename = "test.mp4"; avformat_network_init(); // 打开输入视频文件 AVDictionary *options = nullptr; av_dict_set( &options, "bufsize", "655360", 0 ); av_dict_set( &options, "rtsp_transport", "tcp", 0 ); // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒 ///打开输入的流 ifmt_ctx = avformat_alloc_context(); int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), nullptr, &options); if (ret != 0){ av_log(nullptr, AV_LOG_ERROR, "Couldn't open input stream ! \n"); goto end_flag ; } //查找流信息 if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0){ av_log(nullptr, AV_LOG_ERROR, "Couldn't find stream information ! \n"); goto end_flag ; } // 查找视频流信息 video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); if (video_index < 0) { av_log(nullptr, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n"); goto end_flag ; } //申请AVCodecContext codec_ctx = avcodec_alloc_context3(decoder); if (!codec_ctx){ goto end_flag ; } i_video_stream = ifmt_ctx->streams[video_index]; if(avcodec_parameters_to_context(codec_ctx, i_video_stream->codecpar) < 0){ goto end_flag ; } { av_log(nullptr, AV_LOG_INFO, "path: %s \n", ifmt_ctx->url); av_log(nullptr, AV_LOG_INFO, "format: %s \n", ifmt_ctx->iformat->name); const char* profile = avcodec_profile_name(codec_ctx->codec_id, codec_ctx->profile); av_log(nullptr, AV_LOG_INFO, "codec: %s(%s) \n", decoder->name, profile); const char* pix_fmt_name = av_get_pix_fmt_name(codec_ctx->pix_fmt); av_log(nullptr, AV_LOG_INFO, "pix_fmt_name: %s \n", pix_fmt_name); av_log(nullptr, AV_LOG_INFO, "width x height: %dX%d \n", i_video_stream->codecpar->width, i_video_stream->codecpar->height); av_log(NULL, AV_LOG_INFO, "frame_rate: %1.0f ", av_q2d(i_video_stream->r_frame_rate)); av_log(NULL, AV_LOG_INFO, " --> reference PPS: %f ms\n", 1/av_q2d(i_video_stream->r_frame_rate) * 1000); } avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, filename); /* * since all input files are supposed to be identical (framerate, dimension, color format, ...) * we can safely set output codec values from first input file */ o_video_stream = avformat_new_stream(o_fmt_ctx, NULL); { AVCodecContext *c; c = o_video_stream->codec; c->bit_rate = 400000; c->codec_id = i_video_stream->codec->codec_id; c->codec_type = i_video_stream->codec->codec_type; c->time_base.num = i_video_stream->time_base.num; c->time_base.den = i_video_stream->time_base.den; fprintf(stderr, " = time_base.num = %d time_base.den = %d\n", c->time_base.num, c->time_base.den); c->width = i_video_stream->codec->width; c->height = i_video_stream->codec->height; c->pix_fmt = i_video_stream->codec->pix_fmt; printf(" = width: %d height: %d pix_fmt: %d\n", c->width, c->height, c->pix_fmt); c->flags = i_video_stream->codec->flags; c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; c->me_range = i_video_stream->codec->me_range; c->max_qdiff = i_video_stream->codec->max_qdiff; c->qmin = i_video_stream->codec->qmin; c->qmax = i_video_stream->codec->qmax; c->qcompress = i_video_stream->codec->qcompress; } avio_open(&o_fmt_ctx->pb, filename, AVIO_FLAG_WRITE); avformat_write_header(o_fmt_ctx, NULL); s_time = get_cur_time(); start_time = get_cur_time(); pkt = av_packet_alloc(); while (av_read_frame(ifmt_ctx, pkt) >= 0){ end_time = get_cur_time(); sum ++ ; sep ++ ; if(end_time - start_time > 1000){ avg_time = double(end_time - start_time) / sep; start_time = get_cur_time(); sep = 0; av_log(nullptr, AV_LOG_INFO, "PPS: %f ms\n", avg_time); } av_packet_unref(pkt); } e_time = get_cur_time(); avg_time = double(e_time - s_time) / sum; av_log(nullptr, AV_LOG_INFO, "TOOTAL PPS: %f ms\n", avg_time); end_flag: if (codec_ctx != nullptr){ avcodec_close(codec_ctx); avcodec_free_context(&codec_ctx); } if (ifmt_ctx != nullptr){ avformat_close_input(&ifmt_ctx); } if (pkt != nullptr){ av_packet_free(&pkt); } }