| 706 | | ctx->audio_channels = basic_desc->mChannelsPerFrame; |
| 707 | | ctx->audio_bits_per_sample = basic_desc->mBitsPerChannel; |
| 708 | | ctx->audio_float = basic_desc->mFormatFlags & kAudioFormatFlagIsFloat; |
| 709 | | ctx->audio_be = basic_desc->mFormatFlags & kAudioFormatFlagIsBigEndian; |
| 710 | | ctx->audio_signed_integer = basic_desc->mFormatFlags & kAudioFormatFlagIsSignedInteger; |
| 711 | | ctx->audio_packed = basic_desc->mFormatFlags & kAudioFormatFlagIsPacked; |
| 712 | | ctx->audio_non_interleaved = basic_desc->mFormatFlags & kAudioFormatFlagIsNonInterleaved; |
| | 704 | audio_bits_per_sample = basic_desc->mBitsPerChannel; |
| | 705 | audio_float = basic_desc->mFormatFlags & kAudioFormatFlagIsFloat; |
| | 706 | audio_be = basic_desc->mFormatFlags & kAudioFormatFlagIsBigEndian; |
| | 707 | audio_signed_integer = basic_desc->mFormatFlags & kAudioFormatFlagIsSignedInteger; |
| | 708 | audio_packed = basic_desc->mFormatFlags & kAudioFormatFlagIsPacked; |
| | 709 | audio_non_interleaved = basic_desc->mFormatFlags & kAudioFormatFlagIsNonInterleaved; |
| | 710 | |
| | 711 | if (audio_non_interleaved || !audio_packed) { |
| | 712 | must_convert = 1; |
| | 713 | } |
| | 714 | |
| | 715 | output_format.mBitsPerChannel = basic_desc->mBitsPerChannel; |
| | 716 | output_format.mBytesPerFrame = basic_desc->mBytesPerFrame; |
| | 717 | output_format.mBytesPerPacket = basic_desc->mBytesPerPacket; |
| | 718 | output_format.mChannelsPerFrame = basic_desc->mChannelsPerFrame; |
| | 719 | output_format.mFormatFlags = kAudioFormatFlagIsPacked | audio_be; |
| | 720 | output_format.mFormatID = kAudioFormatLinearPCM; |
| | 721 | output_format.mFramesPerPacket = 1; |
| | 722 | output_format.mReserved = 0; |
| | 723 | output_format.mSampleRate = basic_desc->mSampleRate; |
| 715 | | ctx->audio_float && |
| 716 | | ctx->audio_bits_per_sample == 32 && |
| 717 | | ctx->audio_packed) { |
| 718 | | stream->codecpar->codec_id = ctx->audio_be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE; |
| | 726 | audio_float && |
| | 727 | audio_bits_per_sample == 64) { |
| | 728 | stream->codecpar->codec_id = audio_be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE; |
| | 729 | output_format.mFormatFlags |= kAudioFormatFlagIsFloat; |
| | 730 | } else if (basic_desc->mFormatID == kAudioFormatLinearPCM && |
| | 731 | audio_float && |
| | 732 | audio_bits_per_sample == 32) { |
| | 733 | stream->codecpar->codec_id = audio_be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE; |
| | 734 | output_format.mFormatFlags |= kAudioFormatFlagIsFloat; |
| 730 | | ctx->audio_signed_integer && |
| 731 | | ctx->audio_bits_per_sample == 32 && |
| 732 | | ctx->audio_packed) { |
| 733 | | stream->codecpar->codec_id = ctx->audio_be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE; |
| | 746 | audio_signed_integer && |
| | 747 | audio_bits_per_sample == 32) { |
| | 748 | stream->codecpar->codec_id = audio_be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE; |
| | 749 | output_format.mFormatFlags |= kAudioFormatFlagIsSignedInteger; |
| | 750 | } else if (basic_desc->mFormatID == kAudioFormatLinearPCM && |
| | 751 | audio_signed_integer && |
| | 752 | audio_bits_per_sample == 64) { |
| | 753 | stream->codecpar->codec_id = audio_be ? AV_CODEC_ID_PCM_S64BE : AV_CODEC_ID_PCM_S64LE; |
| | 754 | output_format.mFormatFlags |= kAudioFormatFlagIsSignedInteger; |
| 740 | | if (ctx->audio_non_interleaved) { |
| 741 | | CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(ctx->current_audio_frame); |
| 742 | | ctx->audio_buffer_size = CMBlockBufferGetDataLength(block_buffer); |
| 743 | | ctx->audio_buffer = av_malloc(ctx->audio_buffer_size); |
| 744 | | if (!ctx->audio_buffer) { |
| 745 | | unlock_frames(ctx); |
| 746 | | av_log(s, AV_LOG_ERROR, "error allocating audio buffer\n"); |
| | 762 | if (must_convert) { |
| | 763 | OSStatus ret = AudioConverterNew(basic_desc, &output_format, &ctx->audio_converter); |
| | 764 | if (ret != 0) { |
| | 765 | av_log(s, AV_LOG_ERROR, "Error while allocating audio converter\n"); |
| 1120 | | if (av_new_packet(pkt, block_buffer_size) < 0) { |
| 1121 | | unlock_frames(ctx); |
| 1122 | | return AVERROR(EIO); |
| | 1145 | if (av_new_packet(pkt, output_size) < 0) { |
| | 1146 | return AVERROR(EIO); |
| | 1147 | } |
| | 1148 | |
| | 1149 | ret = AudioConverterConvertBuffer(ctx->audio_converter, block_buffer_size, block_buffer_data, &pkt->size, pkt->data); |
| | 1150 | |
| | 1151 | if (ret != noErr) { |
| | 1152 | return AVERROR(EIO); |
| | 1153 | } |
| | 1154 | } else { |
| | 1155 | if (av_new_packet(pkt, block_buffer_size) < 0) { |
| | 1156 | return AVERROR(EIO); |
| | 1157 | } |
| | 1158 | |
| | 1159 | memcpy(pkt->data, block_buffer_data, pkt->size); |
| 1136 | | if (ctx->audio_non_interleaved) { |
| 1137 | | int sample, c, shift, num_samples; |
| 1138 | | |
| 1139 | | OSStatus ret = CMBlockBufferCopyDataBytes(block_buffer, 0, pkt->size, ctx->audio_buffer); |
| 1140 | | if (ret != kCMBlockBufferNoErr) { |
| 1141 | | unlock_frames(ctx); |
| 1142 | | return AVERROR(EIO); |
| 1143 | | } |
| 1144 | | |
| 1145 | | num_samples = pkt->size / (ctx->audio_channels * (ctx->audio_bits_per_sample >> 3)); |
| 1146 | | |
| 1147 | | // transform decoded frame into output format |
| 1148 | | #define INTERLEAVE_OUTPUT(bps) \ |
| 1149 | | { \ |
| 1150 | | int##bps##_t **src; \ |
| 1151 | | int##bps##_t *dest; \ |
| 1152 | | src = av_malloc(ctx->audio_channels * sizeof(int##bps##_t*)); \ |
| 1153 | | if (!src) { \ |
| 1154 | | unlock_frames(ctx); \ |
| 1155 | | return AVERROR(EIO); \ |
| 1156 | | } \ |
| 1157 | | \ |
| 1158 | | for (c = 0; c < ctx->audio_channels; c++) { \ |
| 1159 | | src[c] = ((int##bps##_t*)ctx->audio_buffer) + c * num_samples; \ |
| 1160 | | } \ |
| 1161 | | dest = (int##bps##_t*)pkt->data; \ |
| 1162 | | shift = bps - ctx->audio_bits_per_sample; \ |
| 1163 | | for (sample = 0; sample < num_samples; sample++) \ |
| 1164 | | for (c = 0; c < ctx->audio_channels; c++) \ |
| 1165 | | *dest++ = src[c][sample] << shift; \ |
| 1166 | | av_freep(&src); \ |
| 1167 | | } |
| 1168 | | |
| 1169 | | if (ctx->audio_bits_per_sample <= 16) { |
| 1170 | | INTERLEAVE_OUTPUT(16) |
| 1171 | | } else { |
| 1172 | | INTERLEAVE_OUTPUT(32) |
| 1173 | | } |
| 1174 | | } else { |
| 1175 | | OSStatus ret = CMBlockBufferCopyDataBytes(block_buffer, 0, pkt->size, pkt->data); |
| 1176 | | if (ret != kCMBlockBufferNoErr) { |
| 1177 | | unlock_frames(ctx); |
| 1178 | | return AVERROR(EIO); |
| 1179 | | } |
| 1180 | | } |
| 1181 | | |