| 706 | } |
| 707 | |
| 708 | ScopedFrame Resize(const AVFrame* input_frame, int width, int height) { |
| 709 | if (!input_frame || input_frame->format != AV_PIX_FMT_RGBA) |
| 710 | throw std::runtime_error("Resize expects an RGBA software frame"); |
| 711 | if (input_frame->width == width && input_frame->height == height) { |
| 712 | ScopedFrame clone(av_frame_clone(input_frame)); |
| 713 | if (!clone) |
| 714 | throw std::runtime_error("Unable to clone RGBA input frame"); |
| 715 | return clone; |
| 716 | } |
| 717 | |
| 718 | sws_context_ = sws_getCachedContext( |
| 719 | sws_context_, |
| 720 | input_frame->width, |
| 721 | input_frame->height, |
| 722 | AV_PIX_FMT_RGBA, |
| 723 | width, |
| 724 | height, |
| 725 | AV_PIX_FMT_RGBA, |
| 726 | SWS_BILINEAR, |
| 727 | nullptr, |
| 728 | nullptr, |
| 729 | nullptr); |
| 730 | if (!sws_context_) |
| 731 | throw std::runtime_error("sws_getCachedContext resize failed"); |
| 732 | |
| 733 | ScopedFrame output_frame; |
| 734 | output_frame.get()->format = AV_PIX_FMT_RGBA; |
| 735 | output_frame.get()->width = width; |
| 736 | output_frame.get()->height = height; |
| 737 | CheckAv(av_frame_get_buffer(output_frame.get(), 32), "av_frame_get_buffer resize"); |
| 738 | CheckAv(av_frame_copy_props(output_frame.get(), input_frame), "av_frame_copy_props resize"); |
| 739 | CheckAv(av_frame_make_writable(output_frame.get()), "av_frame_make_writable resize"); |
| 740 | sws_scale( |
| 741 | sws_context_, |
| 742 | input_frame->data, |
| 743 | input_frame->linesize, |
| 744 | 0, |
| 745 | input_frame->height, |
| 746 | output_frame.get()->data, |
| 747 | output_frame.get()->linesize); |
| 748 | return output_frame; |
| 749 | } |
| 750 | |
| 751 | private: |
| 752 | SwsContext* sws_context_; |
no test coverage detected