| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "util.h" |
| |
| #include <stdarg.h> |
| #include <stddef.h> |
| #include <stdio.h> |
| #include <fstream> |
| #include <iostream> |
| #include <memory> |
| |
| void Exit(const char* format, ...) { |
| // Let's not have a buffer on the stack, not because it couldn't be done |
| // safely, but because we'd potentially run into stack size vs. message length |
| // tradeoffs, stack expansion granularity fun, or whatever else. |
| |
| va_list args; |
| va_start(args, format); |
| size_t buffer_bytes = vsnprintf(nullptr, 0, format, args) + 1; |
| va_end(args); |
| |
| // ~buffer never actually runs since this method never returns |
| std::unique_ptr<char[]> buffer(new char[buffer_bytes]); |
| |
| va_start(args, format); |
| size_t buffer_bytes_2 = |
| vsnprintf(buffer.get(), buffer_bytes, format, args) + 1; |
| (void)buffer_bytes_2; |
| // sanity check; should match so go ahead and assert that it does. |
| assert(buffer_bytes == buffer_bytes_2); |
| va_end(args); |
| |
| printf("%s - exiting\n", buffer.get()); |
| |
| // If anything goes wrong, exit(-1) is used directly (until we have any reason |
| // to do otherwise). |
| exit(-1); |
| } |
| |
| // This is obviously not how anyone would really stream a file, but this example |
| // program isn't about streaming a large media file. |
| std::unique_ptr<uint8_t[]> read_whole_file(const char* filename, size_t* size) { |
| std::ifstream file; |
| // std::ios::ate means start at the end to tellg() will get the size |
| file.open(filename, std::ios::in | std::ios::binary | std::ios::ate); |
| if (!file.is_open()) { |
| Exit("failed to open file"); |
| } |
| std::streampos input_size = file.tellg(); |
| *size = input_size; |
| if (input_size == -1) { |
| Exit("file.tellg() failed"); |
| } |
| VLOGF("file size is: %lld\n", static_cast<long long>(input_size)); |
| std::unique_ptr<uint8_t[]> raw_adts = std::make_unique<uint8_t[]>(input_size); |
| file.seekg(0, std::ios::beg); |
| if (!file) { |
| Exit("file.seekg(0, beg) failed"); |
| } |
| file.read(reinterpret_cast<char*>(raw_adts.get()), input_size); |
| if (!file) { |
| Exit("file.read() failed"); |
| } |
| file.close(); |
| if (!file) { |
| Exit("file.close() failed"); |
| } |
| return raw_adts; |
| } |
| |
| void SHA256_Update_AudioParameters(SHA256_CTX* sha256_ctx, |
| const fuchsia::mediacodec::PcmFormat& pcm) { |
| uint32_t pcm_mode_le = htole32(pcm.pcm_mode); |
| if (!SHA256_Update(sha256_ctx, &pcm_mode_le, sizeof(pcm_mode_le))) { |
| assert(false); |
| } |
| uint32_t bits_per_sample_le = htole32(pcm.bits_per_sample); |
| if (!SHA256_Update(sha256_ctx, &bits_per_sample_le, |
| sizeof(bits_per_sample_le))) { |
| assert(false); |
| } |
| uint32_t frames_per_second_le = htole32(pcm.frames_per_second); |
| if (!SHA256_Update(sha256_ctx, &frames_per_second_le, |
| sizeof(frames_per_second_le))) { |
| assert(false); |
| } |
| for (fuchsia::mediacodec::AudioChannelId channel_id : *pcm.channel_map) { |
| uint32_t channel_id_le = htole32(channel_id); |
| if (!SHA256_Update(sha256_ctx, &channel_id_le, sizeof(channel_id_le))) { |
| assert(false); |
| } |
| } |
| } |