跳转至内容

General Discussion | 综合讨论

A place to talk about whatever you want

19 主题 163 帖子
  • json库的initializer_list创建问题

    已锁定 已解决
    5
    0 赞同
    5 帖子
    35 浏览
    dustchensD

    @SPeak
    按照这个思路,只保留一个列表初始化,用了一个辅助函数检测了每个元素是否是数组,如果是数组就检测长度是否是2,然后首元素是否是string,如果初始化列表里全部元素都符合就判定为object。这个代码运行成功了,感谢大佬

    Json(std::initializer_list<Json> init) { if (is_object_list(init)) { JsonObject dict; for (const auto &el : init) { auto pair = std::get_if<JsonArray>(&el.m_value); // 必须是长度为2的数组 assert(pair && pair->size() == 2); auto key = std::get_if<std::string>(&(*pair)[0].m_value); // 第一个元素必须是字符串 assert(key); dict.emplace(*key, (*pair)[1]); } m_value = std::move(dict); } else { m_value = JsonArray(init); } } bool is_object_list(std::initializer_list<Json> init) { return std::all_of(init.begin(), init.end(), [](const Json &el) { auto pair = std::get_if<JsonArray>(&el.m_value); if (!pair || pair->size() != 2) return false; return std::holds_alternative<std::string>((*pair)[0].m_value); }); }
  • 关于sonic实现音频变速不变调的问题

    11
    0 赞同
    11 帖子
    132 浏览
    Cat-GuijunC

    hi,友友有解决这个情况吗,我也是当speed不为一时就报错了,我完全不知道如何查找崩溃,找了一天了,下面是我的代码:
    void AudioDecodeThread::run()
    {
    // 加入sonic
    // 初始化部分:先创建一个流
    sonicStream stream = sonicCreateStream(m_videoPlayControl->m_audioCodecCtx->sample_rate, 2);
    if (!stream)
    {
    m_videoPlayControl->m_eventHandler->onVideoPlayerError(0, "sonicCreateStream error!");
    }

    if (!initSwrCtx()) { m_videoPlayControl->m_eventHandler->onVideoPlayerError(0, "initSwrCtx error"); return; } while (true) { if (m_videoPlayControl->m_currentState == State::STOP) { break; } else if (m_videoPlayControl->m_currentState == State::PAUSE) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); continue; } AVPacket *pkt = m_videoPlayControl->m_audioPacketQueue.pop(); if (pkt == nullptr) { if (m_videoPlayControl->m_isReadFinished) { break; } continue; } if (memcmp(pkt->data, FLUSHDATA, strlen(FLUSHDATA)) == 0) { avcodec_flush_buffers(m_videoPlayControl->m_audioCodecCtx); av_packet_free(&pkt); continue; } int ret = avcodec_send_packet(m_videoPlayControl->m_audioCodecCtx, pkt); if (ret < 0) { char errbuf[1024] = { 0 }; av_strerror(ret, errbuf, sizeof(errbuf)); fprintf(stderr, "avcodec_send_packet: %s (error pts: %d)\n", errbuf, pkt->pts); av_packet_free(&pkt); continue; } AVFrame *frame = av_frame_alloc(); while (avcodec_receive_frame(m_videoPlayControl->m_audioCodecCtx, frame) == 0) { // 读取frame, swr转换, 放到frameQueue里面去 int inSamples = frame->nb_samples; // int outSamples = av_rescale_rnd(inSamples, 1, 1, AV_ROUND_UP); // 废除手动分配的 audioBuffer,改用 resampleFrame 内部缓冲区 AVFrame *resampleFrame = av_frame_alloc(); resampleFrame->format = AV_SAMPLE_FMT_S16; av_channel_layout_default(&resampleFrame->ch_layout, 2); // 双声道 resampleFrame->sample_rate = frame->sample_rate; // 正确设置采样率 resampleFrame->nb_samples = inSamples; // 让 FFmpeg 自动分配缓冲区(确保地址和大小正确) if (av_frame_get_buffer(resampleFrame, 0) < 0) { av_frame_free(&resampleFrame); continue; } int len = swr_convert(m_swrCtx, resampleFrame->data, resampleFrame->nb_samples, (const uint8_t **)frame->data, inSamples); // 加入sonic sonicSetSpeed(stream, m_videoPlayControl->m_speed); // 4. 写入音频数据到Sonic ,这里的bug short *valid_audio_data = (short *)resampleFrame->data[0]; int total_samples = len; // 单声道总样本数 std::cout << len << std::endl; ret = sonicWriteShortToStream(stream, valid_audio_data, total_samples); if (ret == 0) { m_videoPlayControl->m_eventHandler->onVideoPlayerError(0, "sonicWriteShortToStream error"); continue; } int availableSamples = sonicSamplesAvailable(stream); // if (availableSamples <= 0) { continue; } // 根据实际需要的样本数分配缓冲区 short *output_pcm = new short[availableSamples * 2]; int samples = sonicReadShortFromStream(stream, output_pcm, availableSamples); if (samples <= 0) { delete[] output_pcm; av_frame_free(&resampleFrame); continue; } std::cout << inSamples << "---" << len << "---" << availableSamples << "---" << samples << std::endl; PCMFrame *pcm = new PCMFrame(); pcm->setBuffer((uint8_t *)output_pcm, samples * 4); pcm->setPts(frame->pts); pcm->setSampleRate(frame->sample_rate); m_videoPlayControl->m_audioFrameQueue.push(pcm); delete[] output_pcm; av_frame_free(&resampleFrame); } av_frame_free(&frame); av_packet_free(&pkt); } sonicDestroyStream(stream); }
  • Linux & Win 游戏性能随手记录

    16
    1 赞同
    16 帖子
    529 浏览
    MoYingJiM

    我用错驱动了...
    理论上 上述linux的测试结果还能再提升?

    图片.png

  • 关于 GitHub 中的 Fork 仓库的简单问题

    4
    0 赞同
    4 帖子
    57 浏览
    johanvxJ

    为方便描述,称上游 GitHub 仓库为 upstream,自己 fork 的 GitHub 仓库为 origin。如果没有理解错的话,你应该是遇到下面这个场景并想做到 Step 4:

    = Step 1: Fork * aaaaaa (HEAD -> main, origin/main, upstream/main) ... = Step 2: Make local changes and push them to origin * bbbbbb (HEAD -> main, origin/main) * aaaaaa (upstream/main) ... = Step 3: Check (fetch) upstream's update * bbbbbb (HEAD -> main, origin/main) | * cccccc (upstream/main) |/ * aaaaaa ... = Step 4: Rebase (but how?) * bbbbbb (HEAD -> main, origin/main) * cccccc (upstream/main) * aaaaaa ...

    如果是这样的话,我通常的做法是在本地进行这样的操作:

    git pull -r upstream main # Resolve conflict git rebase --continue

    至于 GitHub 有没有一键(或者几键)的做法,我没有找到。

    参考阅读:https://gitolite.com/git-pull--rebase

  • C++23 gcc15.1 希望有一个CMake历程进行学习!

    已锁定 已解决
    11
    0 赞同
    11 帖子
    196 浏览
    HeiseCurtainH

    非常感谢!!!

  • [wsl编译c++23代码失败]:使用自己编译的gcc15.1

    已移动
    4
    0 赞同
    4 帖子
    101 浏览
    HeiseCurtainH

    image.png你好,我使用了wsl测试,没有问题的。如果需要支持,请提供更详细信息!

  • 0 赞同
    4 帖子
    132 浏览
    SPeakS

    @semmyenator 是的, 需要 [私钥 -map-> 公钥] 是一个不可逆或有限条件下不可逆, 这样才能保证安全性

  • 某小项目关于账号验证的问题...

    2
    0 赞同
    2 帖子
    73 浏览
    sunrisepeakS

    只要在第一次验证后, 让服务器发一个自己的token, 后面就可以使用这个token来获取数据。实在不行可以把这个功能做成可选的 -- 即一次验证(也可手动重新验证, 老的将失效) + 功能可选

  • 此主题已被删除!

    1
    0 赞同
    1 帖子
    17 浏览
    尚无回复
  • 析构函数为何会调用

    已锁定 已解决
    3
    1 赞同
    3 帖子
    135 浏览
    sunrisepeakS

    @CS-liujf 这里T2推导的应该是B类型

  • 你在干什么?

    73
    1 赞同
    73 帖子
    1k 浏览
    sunrisepeakS

    可以先用github的release创建一个0.0.1版本, 或者一个 预览版。基于这个先做一个包文件 以及 验证。后面有变动可以再以版本的方式修改包文件

  • 项目中智能指针多态性丢失的问题

    7
    0 赞同
    7 帖子
    219 浏览
    FrozenLemonTeeF

    已完成。
    最终解决方案是,通过cloneable接口的clone方法,实现具体类对象的动态创建:
    https://github.com/FrozenLemonTee/original/commit/fe14776ccc411790084dcd4ea1a002d3ee22eaa7
    https://github.com/FrozenLemonTee/original/commit/cdd94d92c29c09bb58ca4d6f4b9eadb8272e7e27

  • 关于rt-thread task_struct结构体的疑惑

    2
    0 赞同
    2 帖子
    125 浏览
    sunrisepeakS

    @sky-littlestar 在 关于rt-thread task_struct结构体的疑惑 中说:

    但是一些函数却以此作为类型传参数,task_struct的定义应该怎么找
    找不到使用的地方感觉可以找一找实际的函数中是怎么使用的反推结构里面的成员, 也有可能结构是不公开的

  • opencv无法使用image show,工程可以正常构建生成可执行文件

    已锁定 已移动 已解决
    5
    0 赞同
    5 帖子
    162 浏览
    sunrisepeakS

    @Vilote 在 opencv无法使用image show,工程可以正常构建生成可执行文件 中说:

    implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'

    上面 {不使用系统库} 遇到的问题可能和xmake包管理器的gtk包名问题有关系, 最近两天修复了

    https://github.com/xmake-io/xmake-repo/pull/5748

    可以用下面的命令更新包索引

    xrepo clean xrepo update-repo -f
  • 希望大佬们帮忙review代码,一个workstealing线程池

    3
    0 赞同
    3 帖子
    135 浏览
    sunrisepeakS

    @sunrisepeak 全局队列或许也可以用CAS优化

  • 关于c++ chrono库中类型方面的问题

    已锁定 已解决
    2
    0 赞同
    2 帖子
    112 浏览
    sunrisepeakS

    chrono:xxseconds 一般是duration的别名

    _EXPORT_STD using nanoseconds = duration<long long, nano>; _EXPORT_STD using microseconds = duration<long long, micro>; _EXPORT_STD using milliseconds = duration<long long, milli>; _EXPORT_STD using seconds = duration<long long>; _EXPORT_STD using minutes = duration<int, ratio<60>>; _EXPORT_STD using hours = duration<int, ratio<3600>>;

    而duration的构造存在隐式类型转换, 他的构造函数是一个模板, 在构造函数里会使用duration_cast把std::chrono::milliseconds转成chrono::microseconds

    template <class _Rep2, enable_if_t<is_convertible_v<const _Rep2&, _Rep> && (treat_as_floating_point_v<_Rep> || !treat_as_floating_point_v<_Rep2>), int> = 0> constexpr explicit duration(const _Rep2& _Val) noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v<_Rep2>) // strengthened : _MyRep(static_cast<_Rep>(_Val)) {} template <class _Rep2, class _Period2, enable_if_t<treat_as_floating_point_v<_Rep> || (_Ratio_divide_sfinae<_Period2, _Period>::den == 1 && !treat_as_floating_point_v<_Rep2>), int> = 0> constexpr duration(const duration<_Rep2, _Period2>& _Dur) noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v<_Rep2>) // strengthened : _MyRep(_CHRONO duration_cast<duration>(_Dur).count()) {} // 具体转换的代码 _NODISCARD constexpr _Rep count() const noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { return _MyRep; }

    https://github.com/microsoft/STL/blob/a1bc1261795d4097cf7c12cfd0b5e2091809f281/stl/inc/__msvc_chrono.hpp#L110-L117

  • 如何把imgui和OpenGL结合?

    已锁定 已解决
    7
    0 赞同
    7 帖子
    242 浏览
    lu9943L

    @sunrisepeak 我明白了,原来在imgui的例子里已经有了OpenGL的渲染例子,我报错的原因就是在main里又加了新的OpenGL的渲染代码进去😁 感谢指导

  • 怎么理解aarch64里的堆栈和寄存器?

    已锁定 已解决
    3
    1 赞同
    3 帖子
    149 浏览
    sunrisepeakS

    @lu9943 在 怎么理解aarch64里的堆栈和寄存器? 中说:

    这我就很纳闷了,要是往上生长,那不就是开辟空间是add吗?然后sp不是往上移动了吗?真的被这个绕晕了呀!(文章出处链接文本)

    其实用 往上生长 这个词是不合适的, 因为这设计到 内存图怎么画
    而使用 往低地址生长 进行记忆。 那么:

    如果内存图最上面是地址0, 那就是 往上生长 反之, 如果 内存地址0在最下面 那么就是 往下生长

    333561cb-e053-42a0-8ad7-ed23ac3f7933-image.png