Produce one frame into the container.
Writes pixel data into the container's frame buffer and marks it ready for processing. Returning false means no frame was available this cycle, which is not necessarily an error.
233{
234 if (!container)
235 return false;
236
238 if (!
m_video->is_codec_valid())
239 return false;
240
241 uint8_t* dest = container->mutable_frame_ptr();
242 if (!dest)
243 return false;
244
245 AVPacket* pkt = av_packet_alloc();
246 if (!pkt)
247 return false;
248
249 AVFrame* frame = av_frame_alloc();
250 if (!frame) {
251 av_packet_free(&pkt);
252 return false;
253 }
254
255 bool got_frame = false;
256
257 while (!got_frame) {
258 int ret = av_read_frame(
m_demux->format_context, pkt);
259 if (ret < 0)
260 break;
261
262 if (pkt->stream_index !=
m_video->stream_index) {
263 av_packet_unref(pkt);
264 continue;
265 }
266
267 ret = avcodec_send_packet(
m_video->codec_context, pkt);
268 av_packet_unref(pkt);
269
270 if (ret < 0 && ret != AVERROR(EAGAIN))
271 break;
272
273 ret = avcodec_receive_frame(
m_video->codec_context, frame);
274 if (ret == AVERROR(EAGAIN))
275 continue;
276 if (ret < 0)
277 break;
278
280 if (!
m_video->rebuild_scaler_from_frame(
281 frame,
282 static_cast<uint32_t>(frame->width),
283 static_cast<uint32_t>(frame->height))) {
285 "FFmpegCameraReader: scaler init failed: {}",
287 break;
288 }
289 const size_t buf_bytes =
static_cast<size_t>(
m_video->out_linesize) *
m_video->out_height;
292 }
293
294 uint8_t* sws_dst[1] = {
m_sws_buf.data() };
295 int sws_stride[1] = {
m_video->out_linesize };
296
297 sws_scale(
m_video->sws_context,
298 frame->data, frame->linesize,
299 0,
static_cast<int>(
m_video->height),
300 sws_dst, sws_stride);
301
302 const int packed_stride =
static_cast<int>(
m_video->out_width *
m_video->out_bytes_per_pixel);
303
304 if (
m_video->out_linesize == packed_stride) {
306 static_cast<size_t>(packed_stride) *
m_video->out_height);
307 } else {
308 for (uint32_t row = 0; row <
m_video->out_height; ++row) {
309 std::memcpy(
310 dest + static_cast<size_t>(row) * packed_stride,
312 static_cast<size_t>(packed_stride));
313 }
314 }
315
316 container->mark_ready_for_processing(true);
317 got_frame = true;
318 }
319
320 av_frame_free(&frame);
321 av_packet_free(&pkt);
322
323 return got_frame;
324}
#define MF_ERROR(comp, ctx,...)
std::shared_ptr< FFmpegDemuxContext > m_demux
std::vector< uint8_t > m_sws_buf
std::shared_ptr< VideoStreamContext > m_video
std::shared_mutex m_ctx_mutex
@ Runtime
General runtime operations (default fallback)
@ IO
Networking, file handling, streaming.