| 833 | } |
| 834 | |
| 835 | static ScopedFrame ConvertQImageToAvFrame(const QImage& image) { |
| 836 | QImage rgba = image.convertToFormat(QImage::Format_RGBA8888); |
| 837 | ScopedFrame frame; |
| 838 | if (!frame) { |
| 839 | throw std::runtime_error("Unable to allocate overlay frame"); |
| 840 | } |
| 841 | |
| 842 | frame.get()->format = AV_PIX_FMT_RGBA; |
| 843 | frame.get()->width = rgba.width(); |
| 844 | frame.get()->height = rgba.height(); |
| 845 | CheckAv(av_frame_get_buffer(frame.get(), 32), "av_frame_get_buffer"); |
| 846 | CheckAv(av_frame_make_writable(frame.get()), "av_frame_make_writable"); |
| 847 | |
| 848 | for (int y = 0; y < rgba.height(); ++y) { |
| 849 | std::memcpy(frame.get()->data[0] + y * frame.get()->linesize[0], |
| 850 | rgba.constScanLine(y), |
| 851 | static_cast<size_t>(rgba.width()) * 4); |
| 852 | } |
| 853 | return frame; |
| 854 | } |
| 855 | |
| 856 | struct FilterGraph { |
| 857 | AVFilterGraph* graph = nullptr; |