write all queued frames' audio to the video file
| 1573 | |
| 1574 | // write all queued frames' audio to the video file |
| 1575 | void FFmpegWriter::write_audio_packets(bool is_final, std::shared_ptr<openshot::Frame> frame) { |
| 1576 | if (!frame && !is_final) |
| 1577 | return; |
| 1578 | |
| 1579 | // Init audio buffers / variables |
| 1580 | int total_frame_samples = 0; |
| 1581 | int frame_position = 0; |
| 1582 | int channels_in_frame = 0; |
| 1583 | int sample_rate_in_frame = 0; |
| 1584 | int samples_in_frame = 0; |
| 1585 | ChannelLayout channel_layout_in_frame = LAYOUT_MONO; // default channel layout |
| 1586 | |
| 1587 | // Create a new array (to hold all S16 audio samples, for the current queued frames |
| 1588 | unsigned int all_queued_samples_size = sizeof(int16_t) * AVCODEC_MAX_AUDIO_FRAME_SIZE; |
| 1589 | int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size); |
| 1590 | int16_t *all_resampled_samples = NULL; |
| 1591 | int16_t *final_samples_planar = NULL; |
| 1592 | int16_t *final_samples = NULL; |
| 1593 | |
| 1594 | // Get audio sample array |
| 1595 | float *frame_samples_float = NULL; |
| 1596 | |
| 1597 | // Get the audio details from this frame |
| 1598 | if (frame) { |
| 1599 | sample_rate_in_frame = frame->SampleRate(); |
| 1600 | samples_in_frame = frame->GetAudioSamplesCount(); |
| 1601 | channels_in_frame = frame->GetAudioChannelsCount(); |
| 1602 | channel_layout_in_frame = frame->ChannelsLayout(); |
| 1603 | |
| 1604 | // Get samples interleaved together (c1 c2 c1 c2 c1 c2) |
| 1605 | frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame); |
| 1606 | } |
| 1607 | |
| 1608 | // Calculate total samples |
| 1609 | total_frame_samples = samples_in_frame * channels_in_frame; |
| 1610 | |
| 1611 | // Translate audio sample values back to 16 bit integers with saturation |
| 1612 | const int16_t max16 = 32767; |
| 1613 | const int16_t min16 = -32768; |
| 1614 | for (int s = 0; s < total_frame_samples; s++, frame_position++) { |
| 1615 | float valF = frame_samples_float[s] * (1 << 15); |
| 1616 | int16_t conv; |
| 1617 | if (valF > max16) { |
| 1618 | conv = max16; |
| 1619 | } else if (valF < min16) { |
| 1620 | conv = min16; |
| 1621 | } else { |
| 1622 | conv = int(valF + 32768.5) - 32768; // +0.5 is for rounding |
| 1623 | } |
| 1624 | |
| 1625 | // Copy into buffer |
| 1626 | all_queued_samples[frame_position] = conv; |
| 1627 | } |
| 1628 | |
| 1629 | // Deallocate float array |
| 1630 | delete[] frame_samples_float; |
| 1631 | |
| 1632 |
nothing calls this directly
no test coverage detected