blob: ae6174e0703cde9d50109ed162d9e38fea869c4c [file] [log] [blame]
// 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 <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 %s", filename);
}
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 PostSerial(async_dispatcher_t* dispatcher, fit::closure to_run) {
zx_status_t post_result = async::PostTask(dispatcher, std::move(to_run));
if (post_result != ZX_OK) {
Exit("async::PostTask() failed - post_result: %d", post_result);
}
}
void SHA256_Update_AudioParameters(SHA256_CTX* sha256_ctx,
const fuchsia::media::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::media::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);
}
}
}
void SHA256_Update_VideoParameters(
SHA256_CTX* sha256_ctx,
const fuchsia::media::VideoUncompressedFormat& video) {
UpdateSha256(sha256_ctx, video.fourcc);
UpdateSha256(sha256_ctx, video.primary_width_pixels);
UpdateSha256(sha256_ctx, video.primary_height_pixels);
UpdateSha256(sha256_ctx, video.secondary_width_pixels);
UpdateSha256(sha256_ctx, video.secondary_height_pixels);
UpdateSha256(sha256_ctx, video.planar);
UpdateSha256(sha256_ctx, video.swizzled);
UpdateSha256(sha256_ctx, video.primary_line_stride_bytes);
UpdateSha256(sha256_ctx, video.secondary_line_stride_bytes);
UpdateSha256(sha256_ctx, video.primary_start_offset);
UpdateSha256(sha256_ctx, video.secondary_start_offset);
UpdateSha256(sha256_ctx, video.tertiary_start_offset);
UpdateSha256(sha256_ctx, video.primary_pixel_stride);
UpdateSha256(sha256_ctx, video.secondary_pixel_stride);
UpdateSha256(sha256_ctx, video.special_formats.is_temp_field_todo_remove());
UpdateSha256(sha256_ctx, video.special_formats.temp_field_todo_remove());
}
void SHA256_Update_VideoPlane(SHA256_CTX* sha256_ctx, uint8_t* start,
uint32_t width, uint32_t stride,
uint32_t height) {
uint8_t* src = start;
for (uint32_t row = 0; row < height; ++row) {
SHA256_Update(sha256_ctx, src, width);
src += stride;
}
}