Decode one frame from the device into the container's m_data[0].
Pumps packets until one decoded frame is available, converts to RGBA via swscale into container->mutable_frame_ptr(), then calls container->mark_ready_for_processing(true). Returns false on EAGAIN (no frame yet) — not an error, just no data available this cycle.
The caller is responsible for invoking this once per graphics cycle, before the container's process_default() is triggered by downstream consumers. Typical integration: register as a graphics pre_process_hook or call explicitly before buffer processing.
154{
155 if (!container)
156 return false;
157
159 if (!
m_video->is_codec_valid())
160 return false;
161
162 uint8_t* dest = container->mutable_frame_ptr();
163 if (!dest)
164 return false;
165
166 AVPacket* pkt = av_packet_alloc();
167 if (!pkt)
168 return false;
169
170 AVFrame* frame = av_frame_alloc();
171 if (!frame) {
172 av_packet_free(&pkt);
173 return false;
174 }
175
176 bool got_frame = false;
177
178 while (!got_frame) {
179 int ret = av_read_frame(
m_demux->format_context, pkt);
180 if (ret < 0)
181 break;
182
183 if (pkt->stream_index !=
m_video->stream_index) {
184 av_packet_unref(pkt);
185 continue;
186 }
187
188 ret = avcodec_send_packet(
m_video->codec_context, pkt);
189 av_packet_unref(pkt);
190
191 if (ret < 0 && ret != AVERROR(EAGAIN))
192 break;
193
194 ret = avcodec_receive_frame(
m_video->codec_context, frame);
195 if (ret == AVERROR(EAGAIN))
196 continue;
197 if (ret < 0)
198 break;
199
201 if (!
m_video->rebuild_scaler_from_frame(
202 frame,
203 static_cast<uint32_t>(frame->width),
204 static_cast<uint32_t>(frame->height))) {
206 "CameraReader: scaler init failed: {}",
208 break;
209 }
210 const size_t buf_bytes =
static_cast<size_t>(
m_video->out_linesize) *
m_video->out_height;
213 }
214
215 uint8_t* sws_dst[1] = {
m_sws_buf.data() };
216 int sws_stride[1] = {
m_video->out_linesize };
217
218 sws_scale(
m_video->sws_context,
219 frame->data, frame->linesize,
220 0,
static_cast<int>(
m_video->height),
221 sws_dst, sws_stride);
222
223 const int packed_stride =
static_cast<int>(
m_video->out_width *
m_video->out_bytes_per_pixel);
224
225 if (
m_video->out_linesize == packed_stride) {
227 static_cast<size_t>(packed_stride) *
m_video->out_height);
228 } else {
229 for (uint32_t row = 0; row <
m_video->out_height; ++row) {
230 std::memcpy(
231 dest + static_cast<size_t>(row) * packed_stride,
233 static_cast<size_t>(packed_stride));
234 }
235 }
236
237 container->mark_ready_for_processing(true);
238 got_frame = true;
239 }
240
241 av_frame_free(&frame);
242 av_packet_free(&pkt);
243
244 return got_frame;
245}
#define MF_ERROR(comp, ctx,...)
std::vector< uint8_t > m_sws_buf
std::shared_mutex m_ctx_mutex
std::shared_ptr< VideoStreamContext > m_video
std::shared_ptr< FFmpegDemuxContext > m_demux
@ Runtime
General runtime operations (default fallback)
@ IO
Networking, file handling, streaming.