| 426 | } |
| 427 | |
| 428 | static int receive_samples(SyncQueue *sq, SyncQueueStream *st, |
| 429 | AVFrame *dst, int nb_samples) |
| 430 | { |
| 431 | SyncQueueFrame src; |
| 432 | int ret; |
| 433 | |
| 434 | av_assert0(st->samples_queued >= nb_samples); |
| 435 | |
| 436 | ret = av_container_fifo_peek(st->fifo, (void**)&src, 0); |
| 437 | av_assert0(ret >= 0); |
| 438 | |
| 439 | // peeked frame has enough samples and its data is aligned |
| 440 | // -> we can just make a reference and limit its sample count |
| 441 | if (src.f->nb_samples > nb_samples && frame_is_aligned(sq, src.f)) { |
| 442 | ret = av_frame_ref(dst, src.f); |
| 443 | if (ret < 0) |
| 444 | return ret; |
| 445 | |
| 446 | dst->nb_samples = nb_samples; |
| 447 | offset_audio(src.f, nb_samples); |
| 448 | st->samples_queued -= nb_samples; |
| 449 | |
| 450 | goto finish; |
| 451 | } |
| 452 | |
| 453 | // otherwise allocate a new frame and copy the data |
| 454 | ret = av_channel_layout_copy(&dst->ch_layout, &src.f->ch_layout); |
| 455 | if (ret < 0) |
| 456 | return ret; |
| 457 | |
| 458 | dst->format = src.f->format; |
| 459 | dst->nb_samples = nb_samples; |
| 460 | |
| 461 | ret = av_frame_get_buffer(dst, 0); |
| 462 | if (ret < 0) |
| 463 | goto fail; |
| 464 | |
| 465 | ret = av_frame_copy_props(dst, src.f); |
| 466 | if (ret < 0) |
| 467 | goto fail; |
| 468 | |
| 469 | dst->nb_samples = 0; |
| 470 | while (dst->nb_samples < nb_samples) { |
| 471 | int to_copy; |
| 472 | |
| 473 | ret = av_container_fifo_peek(st->fifo, (void**)&src, 0); |
| 474 | av_assert0(ret >= 0); |
| 475 | |
| 476 | to_copy = FFMIN(nb_samples - dst->nb_samples, src.f->nb_samples); |
| 477 | |
| 478 | av_samples_copy(dst->extended_data, src.f->extended_data, dst->nb_samples, |
| 479 | 0, to_copy, dst->ch_layout.nb_channels, dst->format); |
| 480 | |
| 481 | if (to_copy < src.f->nb_samples) |
| 482 | offset_audio(src.f, to_copy); |
| 483 | else |
| 484 | av_container_fifo_drain(st->fifo, 1); |
| 485 |
no test coverage detected