当前位置: 首页 > news >正文

上海模板开发建站wordpress在新窗口打开

上海模板开发建站,wordpress在新窗口打开,装修照片,湖南火电建设有限公司网站以下测试代码实现的功能是#xff1a;持续从内存块中获取原始数据#xff0c;然后依次进行解码、编码、最后保存成mp4视频文件。 可保存成单个视频文件#xff0c;也可指定每个视频文件的总帧数#xff0c;保存多个视频文件。 为了便于查看和修改#xff0c;这里将可独立的…      以下测试代码实现的功能是持续从内存块中获取原始数据然后依次进行解码、编码、最后保存成mp4视频文件。 可保存成单个视频文件也可指定每个视频文件的总帧数保存多个视频文件。 为了便于查看和修改这里将可独立的程序段存放在单个函数中 1.线程函数set_packet独立线程用于用户向指定的内存块中持续写入数据这里通过调用队列类PacketScaleQueue可参考https://blog.csdn.net/fengbingchun/article/details/132128885 中说明。这里填充的数据参考FFmpeg源码中的doc/examples/encode_video.c每次向队列中写入一帧数据 void set_packet(PacketScaleQueue packet_encode) {while (packet_encode_flag) {Buffer buffer;packet_encode.popPacket(buffer);static int i 0;// refrence: ffmpeg/doc/examples/encode_video.c// prepare a dummy image: Yunsigned char* p1 buffer.data;for (auto y 0; y height; y) {for (auto x 0; x width; x) {p1[y * width x] x y i * 3;}}// Cb and Crunsigned char* p2 buffer.data width * height;unsigned char* p3 buffer.data width * height width * height / 4;for (auto y 0; y height / 2; y) {for (auto x 0; x width / 2; x) {p2[y * width / 2 x] 128 y i * 2;p3[y * width / 2 x] 64 x i * 5;}}packet_encode.pushScale(buffer);if (i 25) i 0;std::this_thread::sleep_for(std::chrono::milliseconds(40));} } 2.回调函数read_packetavio_alloc_context中使用不断从队列中获取数据av_read_frame中也会从这里获取数据每次从队列中获取一帧数据 int read_packet(void* opaque, uint8_t* buf, int buf_size) {PacketScaleQueue* packet_encode static_castPacketScaleQueue*(opaque);Buffer buffer;packet_encode-popScale(buffer);memcpy(buf, buffer.data, buf_size);packet_encode-pushPacket(buffer);return buf_size; } 3.函数get_input_format_context创建输入AVFormatContext需要调用av_dict_set设置video_size和pixel_format AVFormatContext* get_input_format_context(AVIOContext* avio_ctx) {AVFormatContext* ifmt_ctx avformat_alloc_context();if (!ifmt_ctx) {print_error_string(AVERROR(ENOMEM));return nullptr;}ifmt_ctx-pb avio_ctx;AVDictionary* dict nullptr;av_dict_set(dict, video_size, video_size, 0);av_dict_set(dict, pixel_format, pixel_format, 0);auto ret avformat_open_input(ifmt_ctx, nullptr, av_find_input_format(rawvideo), dict);if (ret 0) {fprintf(stderr, Could not open input\n);print_error_string(ret);return nullptr;}av_dict_free(dict);ret avformat_find_stream_info(ifmt_ctx, nullptr);if (ret 0) {fprintf(stderr, Could not find stream information\n);print_error_string(ret);return nullptr;}for (unsigned int i 0; i ifmt_ctx-nb_streams; i) {const AVStream* stream ifmt_ctx-streams[i];if (stream-codecpar-codec_type AVMEDIA_TYPE_VIDEO) {video_stream_index i;fprintf(stdout, type of the encoded data: %d, dimensions of the video frame in pixels: width: %d, height: %d, pixel format: %d\n,stream-codecpar-codec_id, stream-codecpar-width, stream-codecpar-height, stream-codecpar-format);}}if (video_stream_index -1) {fprintf(stderr, error: no video stream\n);return nullptr;}if (ifmt_ctx-streams[video_stream_index]-codecpar-codec_id ! AV_CODEC_ID_RAWVIDEO) {fprintf(stderr, error: this test code only support rawvideo encode: %d\n, ifmt_ctx-streams[video_stream_index]-codecpar-codec_id);return nullptr;}av_dump_format(ifmt_ctx, 0, nothing, 0);return ifmt_ctx; } 4.函数get_decode_context创建解码AVCodecContext AVCodecContext* get_decode_context(AVFormatContext* ifmt_ctx) {AVCodec* decoder nullptr;auto ret av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, decoder, 0);if (ret 0) {fprintf(stderr, fail to av_find_best_stream: %d\n, ret);print_error_string(ret);return nullptr;}AVCodecContext* dec_ctx avcodec_alloc_context3(decoder);if (!dec_ctx) {fprintf(stderr, fail to avcodec_alloc_context3\n);return nullptr;}ret avcodec_parameters_to_context(dec_ctx, ifmt_ctx-streams[video_stream_index]-codecpar);if (ret 0) {fprintf(stderr, fail to avcodec_parameters_to_context: %d\n, ret);print_error_string(ret);return nullptr;}dec_ctx-framerate av_guess_frame_rate(ifmt_ctx, ifmt_ctx-streams[video_stream_index], nullptr);ret avcodec_open2(dec_ctx, decoder, nullptr);if (ret ! 0) {fprintf(stderr, fail to avcodec_open2: %d\n, ret);print_error_string(ret);return nullptr;}return dec_ctx; } 5.函数get_encode_context创建编码AVCodecContext注意对enc_ctx的相关成员的赋值 AVCodecContext* get_encode_context(AVFormatContext* ifmt_ctx) {AVCodec* encodec avcodec_find_encoder_by_name(mpeg1video); // ffmpeg.exe -encodersif (!encodec) {fprintf(stderr, fail to avcodec_find_encoder_by_name\n);return nullptr;}AVCodecContext* enc_ctx avcodec_alloc_context3(encodec);if (!enc_ctx) {fprintf(stderr, fail to avcodec_alloc_context3\n);return nullptr;}enc_ctx-bit_rate 400000;enc_ctx-framerate ifmt_ctx-streams[video_stream_index]-r_frame_rate;enc_ctx-pix_fmt AV_PIX_FMT_YUV420P;enc_ctx-height ifmt_ctx-streams[video_stream_index]-codecpar-height;enc_ctx-width ifmt_ctx-streams[video_stream_index]-codecpar-width;enc_ctx-time_base av_inv_q(av_d2q(frame_rate, 4096));enc_ctx-max_b_frames 1;//if (ofmt_ctx-oformat-flags AVFMT_GLOBALHEADER) // trueenc_ctx-flags | AV_CODEC_FLAG_GLOBAL_HEADER;auto ret avcodec_open2(enc_ctx, encodec, nullptr);if (ret ! 0) {fprintf(stderr, fail to avcodec_open2: %d\n, ret);print_error_string(ret);return nullptr;}return enc_ctx; } 6.函数get_output_format_context创建输出AVFormatContext AVFormatContext* get_output_format_context(const AVCodecContext* enc_ctx, const char* filename) {AVFormatContext* ofmt_ctx nullptr;auto ret avformat_alloc_output_context2(ofmt_ctx, nullptr, nullptr, filename);if (ret 0 || !ofmt_ctx) {fprintf(stderr, fail to avformat_alloc_output_context2: %d\n, ret);print_error_string(ret);return nullptr;}AVStream* out_stream avformat_new_stream(ofmt_ctx, nullptr);if (!out_stream) {fprintf(stderr, fail to avformat_new_stream\n);return nullptr;}ret avcodec_parameters_from_context(out_stream-codecpar, enc_ctx);if (ret 0) {fprintf(stderr, fail to avcodec_parameters_from_context: %d\n, ret);print_error_string(ret);return nullptr;}out_stream-time_base enc_ctx-time_base;if (!(ofmt_ctx-oformat-flags AVFMT_NOFILE)) { // trueret avio_open(ofmt_ctx-pb, filename, AVIO_FLAG_WRITE);if (ret 0) {fprintf(stderr, fail to avio_open: %d\n, ret);print_error_string(ret);return nullptr;}}ret avformat_write_header(ofmt_ctx, nullptr);if (ret 0) {fprintf(stderr, fail to avformat_write_header: %d\n, ret);print_error_string(ret);return nullptr;}av_dump_format(ofmt_ctx, 0, filename, 1);return ofmt_ctx; } 7.函数decode: 注意对packet的判断它有可能为nullptr调用一次avcodec_send_packet可能需调用多次avcodec_receive_frame因此需要将avcodec_receive_frame放在while中需要对dec_ctx-time_base进行设置 int decode(AVPacket* packet, AVFormatContext* ifmt_ctx, AVCodecContext* dec_ctx, AVFrame* frame) {if (packet)av_packet_rescale_ts(packet, ifmt_ctx-streams[video_stream_index]-time_base, dec_ctx-time_base);auto ret avcodec_send_packet(dec_ctx, packet);if (ret 0) {fprintf(stderr, fail to avcodec_send_packet: %d\n, ret);print_error_string(ret);return -1;}while (1) {ret avcodec_receive_frame(dec_ctx, frame);if (ret AVERROR(EAGAIN) || ret AVERROR_EOF) { // AVERROR(EAGAIN): decode is not yet complete//fprintf(stderr, Warning: avcodec_receive_frame: %d\n, ret);//print_error_string(ret);break;}else if (ret 0) {fprintf(stderr, fail to avcodec_receive_frame: %d\n, ret);print_error_string(ret);return ret;}frame-pts frame-best_effort_timestamp;break;}if (packet)av_packet_unref(packet);return 0; } 8.函数encode注意调用一次avcodec_send_frame可能需要调用多次avcodec_receive_packet因此需要将avcodec_receive_packet放在while中需要对ofmt_ctx-streams[0]-time_base进行设置否则生成的mp4中无法获取帧速率也可在调用avformat_write_header时设置video_track_timescale指定 int encode(AVCodecContext* enc_ctx, AVFrame* frame, AVPacket* packet, AVFormatContext* ifmt_ctx, AVFormatContext* ofmt_ctx) {auto ret avcodec_send_frame(enc_ctx, frame);if (ret 0) {if (ret AVERROR(EAGAIN) || ret AVERROR_EOF) {fprintf(stderr, Warning: avcodec_send_frame: %d\n, ret);print_error_string(ret);ret 0;}else {fprintf(stderr, fail to avcodec_send_frame: %d\n, ret);print_error_string(ret);return ret;}}while (1) {ret avcodec_receive_packet(enc_ctx, packet);if (ret AVERROR(EAGAIN) || ret AVERROR_EOF) { // AVERROR(EAGAIN): encode is not yet complete//fprintf(stderr, Warning: avcodec_receive_packet: %d\n, ret);//print_error_string(ret);break;}if (ret 0) {fprintf(stderr, fail to avcodec_receive_packet: %d\n, ret);print_error_string(ret);return ret;}packet-stream_index 0;av_packet_rescale_ts(packet, ifmt_ctx-streams[video_stream_index]-time_base, ofmt_ctx-streams[0]-time_base);//packet2-pts packet2-dts frame-pts *// ofmt_ctx-streams[0]-time_base.den / ofmt_ctx-streams[0]-time_base.num / // (enc_ctx-framerate.num / enc_ctx-framerate.den);ret av_interleaved_write_frame(ofmt_ctx, packet);if (ret 0) {print_error_string(ret);return ret;}av_packet_unref(packet);}return 0; } 9.主函数test_ffmpeg_save_video_slice注意在退出前需要flush decoder和encoder写入视频文件需先调用avformat_write_header然后持续调用av_interleaved_write_frame退出前再需调用av_write_trailer每次新文件的写入需重新调用get_decode_context、get_encode_context、get_output_format_context并在之前作相应free int test_ffmpeg_save_video_slice() {PacketScaleQueue packet_encode;packet_encode.init(queue_size, block_size);std::thread thread_packet(set_packet, std::ref(packet_encode));uint8_t* avio_ctx_buffer static_castuint8_t*(av_malloc(block_size));if (!avio_ctx_buffer) {print_error_string(AVERROR(ENOMEM));return -1;}AVIOContext* avio_ctx avio_alloc_context(avio_ctx_buffer, block_size, 0, packet_encode, read_packet, nullptr, nullptr);if (!avio_ctx) {print_error_string(AVERROR(ENOMEM));return -1;}AVFormatContext* ifmt_ctx get_input_format_context(avio_ctx);if (!ifmt_ctx) {fprintf(stderr, fail to get_input_format_context\n);return -1;}AVPacket *packet av_packet_alloc(), *packet2 av_packet_alloc();if (!packet || !packet2) {fprintf(stderr, fail to av_packet_alloc\n);return -1;}AVFrame* frame av_frame_alloc();if (!frame) {fprintf(stderr, fail to av_frame_alloc\n);return -1;}int count 0, name 1;AVCodecContext* enc_ctx nullptr;AVFormatContext* ofmt_ctx nullptr;AVCodecContext* dec_ctx nullptr;while (1) {auto ret av_read_frame(ifmt_ctx, packet);if (ret 0) {break;}if (packet-stream_index ! video_stream_index) {av_packet_unref(packet);continue;}if (count % slice_size 0) {enc_ctx get_encode_context(ifmt_ctx);if (!enc_ctx) {fprintf(stderr, fail to avcodec_alloc_context3\n);return -1;}std::string filename std::to_string(name) .mp4;filename std::string(path) filename;ofmt_ctx get_output_format_context(enc_ctx, filename.c_str());if (!ofmt_ctx) {fprintf(stderr, fail to get_output_format_context\n);return -1;}dec_ctx get_decode_context(ifmt_ctx);if (!dec_ctx) {fprintf(stderr, fail to get_decode_context\n);return -1;}name;}if (decode(packet, ifmt_ctx, dec_ctx, frame) ! 0) return -1;if (encode(enc_ctx, frame, packet2, ifmt_ctx, ofmt_ctx) ! 0) return -1;//fprintf(stdout, count: %d\n, count);if (count 1 total_frames) { // terminate looppacket_encode_flag false;// flush the decoderdecode(nullptr, ifmt_ctx, dec_ctx, frame);if (frame-data[0])encode(enc_ctx, frame, packet2, ifmt_ctx, ofmt_ctx);// flush the encoderencode(enc_ctx, nullptr, packet2, ifmt_ctx, ofmt_ctx);av_write_trailer(ofmt_ctx);break;}count;if (count 1 count % slice_size 0) {// flush the decoderdecode(nullptr, ifmt_ctx, dec_ctx, frame);if (frame-data[0])encode(enc_ctx, frame, packet2, ifmt_ctx, ofmt_ctx);// flush the encoderencode(enc_ctx, nullptr, packet2, ifmt_ctx, ofmt_ctx);av_write_trailer(ofmt_ctx);avcodec_free_context(dec_ctx);avcodec_free_context(enc_ctx);avio_closep(ofmt_ctx-pb);avformat_free_context(ofmt_ctx);}}av_packet_free(packet);av_packet_free(packet2);av_frame_free(frame);avcodec_free_context(dec_ctx);avcodec_free_context(enc_ctx);avio_closep(ofmt_ctx-pb);avformat_close_input(ofmt_ctx);avformat_close_input(ifmt_ctx);// note: the internal buffer could have changed, and be ! avio_ctx_bufferif (avio_ctx) {av_freep(avio_ctx-buffer);av_freep(avio_ctx);}thread_packet.join();fprintf(stdout, test finish\n);return 0; } 执行结果如下图所示 可调用ffprobe.exe验证每个生成的视频文件的总帧数如1.mp4,执行如下命令 ffprobe.exe -v error -select_streams v:0 -show_entries streamnb_frames -of defaultnokey1:noprint_wrappers1 1.mp4 GitHubhttps://github.com/fengbingchun/OpenCV_Test
http://www.sadfv.cn/news/65653/

相关文章:

  • 网站建设中的html页面网站建设流程代理商
  • 高端网站建设公司有哪些项目aspx高性能网站建设
  • 成都行业网站建设那里好深圳设计网站费用
  • 济南app网站建设word文档怎么做网站跳转链接
  • cms网站建设商业空间设计案例
  • 先做网站还是先域名备案南安seo关键词
  • 官方网站做自适应好还是响应式北京网站建设的服务商
  • 国内自建的海淘网站简述搜索引擎的工作原理
  • 成立学校网站建设小组网站域名注册申请
  • 唐山住房和城乡建设局网站做网站界面一般用什么来做
  • 网站优化seo培韩国儿童才艺网站建设模板
  • 长春火车站咨询电话百度信息流网站可以做落地页吗
  • 做彩票的网站有哪些重庆网站商城
  • 做名片赞机器人电脑网站是多少钱近期的新新闻
  • 哪个网站可以做身份核验网站开发与设计开题报告
  • 莱芜找工作网站广告设计公司名字大全
  • 网站构建是什么ui设计流程培训网站
  • 网站建议怎么写电子商务网站建设的方法
  • 盐田区住房和建设局网站东莞网络营销型网站
  • 深圳外贸网站开发网站如何留住用户
  • 网站开发评估与调整抖音小程序怎么入驻
  • 商务网站建设的六个步骤wordpress autop
  • 为什么只有中国做网站需要备案企业网站类型
  • 临沂网站制作建设wordpress加密插件
  • 重庆网站设计平台创新的沈阳网站建设
  • 绵阳高新区建设局网站网站链接改名怎做301
  • 网站建设跳转页面怎么弄快速排名新
  • 国外公共空间设计网站学校网络营销推广方案
  • 商业网站最佳域名哈尔滨道外区建设局官方网站
  • 企业qq手机版下载seo新手快速入门