MCPcopy Create free account
hub / github.com/ClassicOldSong/Apollo / convert

Method convert

src/video.cpp:138–182  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

136 class avcodec_software_encode_device_t: public platf::avcodec_encode_device_t {
137 public:
138 int convert(platf::img_t &img) override {
139 // If we need to add aspect ratio padding, we need to scale into an intermediate output buffer
140 bool requires_padding = (sw_frame->width != sws_output_frame->width || sw_frame->height != sws_output_frame->height);
141
142 // Setup the input frame using the caller's img_t
143 sws_input_frame->data[0] = img.data;
144 sws_input_frame->linesize[0] = img.row_pitch;
145
146 // Perform color conversion and scaling to the final size
147 auto status = sws_scale_frame(sws.get(), requires_padding ? sws_output_frame.get() : sw_frame.get(), sws_input_frame.get());
148 if (status < 0) {
149 char string[AV_ERROR_MAX_STRING_SIZE];
150 BOOST_LOG(error) << "Couldn't scale frame: "sv << av_make_error_string(string, AV_ERROR_MAX_STRING_SIZE, status);
151 return -1;
152 }
153
154 // If we require aspect ratio padding, copy the output frame into the final padded frame
155 if (requires_padding) {
156 auto fmt_desc = av_pix_fmt_desc_get((AVPixelFormat) sws_output_frame->format);
157 auto planes = av_pix_fmt_count_planes((AVPixelFormat) sws_output_frame->format);
158 for (int plane = 0; plane < planes; plane++) {
159 auto shift_h = plane == 0 ? 0 : fmt_desc->log2_chroma_h;
160 auto shift_w = plane == 0 ? 0 : fmt_desc->log2_chroma_w;
161 auto offset = ((offsetW >> shift_w) * fmt_desc->comp[plane].step) + (offsetH >> shift_h) * sw_frame->linesize[plane];
162
163 // Copy line-by-line to preserve leading padding for each row
164 for (int line = 0; line < sws_output_frame->height >> shift_h; line++) {
165 memcpy(sw_frame->data[plane] + offset + (line * sw_frame->linesize[plane]), sws_output_frame->data[plane] + (line * sws_output_frame->linesize[plane]), (size_t) (sws_output_frame->width >> shift_w) * fmt_desc->comp[plane].step);
166 }
167 }
168 }
169
170 // If frame is not a software frame, it means we still need to transfer from main memory
171 // to vram memory
172 if (frame->hw_frames_ctx) {
173 auto status = av_hwframe_transfer_data(frame, sw_frame.get(), 0);
174 if (status < 0) {
175 char string[AV_ERROR_MAX_STRING_SIZE];
176 BOOST_LOG(error) << "Failed to transfer image data to hardware frame: "sv << av_make_error_string(string, AV_ERROR_MAX_STRING_SIZE, status);
177 return -1;
178 }
179 }
180
181 return 0;
182 }
183
184 int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
185 this->frame = frame;

Callers

nothing calls this directly

Calls 1

getMethod · 0.45

Tested by

no test coverage detected