1c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* libFLAC - Free Lossless Audio Codec 2c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson 3c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 4c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Redistribution and use in source and binary forms, with or without 5c74663799493f2b1e6123c18def94295d0afab7Kenny Root * modification, are permitted provided that the following conditions 6c74663799493f2b1e6123c18def94295d0afab7Kenny Root * are met: 7c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 8c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Redistributions of source code must retain the above copyright 9c74663799493f2b1e6123c18def94295d0afab7Kenny Root * notice, this list of conditions and the following disclaimer. 10c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 11c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Redistributions in binary form must reproduce the above copyright 12c74663799493f2b1e6123c18def94295d0afab7Kenny Root * notice, this list of conditions and the following disclaimer in the 13c74663799493f2b1e6123c18def94295d0afab7Kenny Root * documentation and/or other materials provided with the distribution. 14c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 15c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Neither the name of the Xiph.org Foundation nor the names of its 16c74663799493f2b1e6123c18def94295d0afab7Kenny Root * contributors may be used to endorse or promote products derived from 17c74663799493f2b1e6123c18def94295d0afab7Kenny Root * this software without specific prior written permission. 18c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 19c74663799493f2b1e6123c18def94295d0afab7Kenny Root * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20c74663799493f2b1e6123c18def94295d0afab7Kenny Root * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21c74663799493f2b1e6123c18def94295d0afab7Kenny Root * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22c74663799493f2b1e6123c18def94295d0afab7Kenny Root * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 23c74663799493f2b1e6123c18def94295d0afab7Kenny Root * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24c74663799493f2b1e6123c18def94295d0afab7Kenny Root * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25c74663799493f2b1e6123c18def94295d0afab7Kenny Root * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26c74663799493f2b1e6123c18def94295d0afab7Kenny Root * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27c74663799493f2b1e6123c18def94295d0afab7Kenny Root * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28c74663799493f2b1e6123c18def94295d0afab7Kenny Root * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29c74663799493f2b1e6123c18def94295d0afab7Kenny Root * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30c74663799493f2b1e6123c18def94295d0afab7Kenny Root */ 31c74663799493f2b1e6123c18def94295d0afab7Kenny Root 32c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if HAVE_CONFIG_H 33c74663799493f2b1e6123c18def94295d0afab7Kenny Root# include <config.h> 34c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif 35c74663799493f2b1e6123c18def94295d0afab7Kenny Root 36c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <string.h> /* for memset() */ 37c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "FLAC/assert.h" 38c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/ogg_encoder_aspect.h" 39c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/ogg_mapping.h" 40c74663799493f2b1e6123c18def94295d0afab7Kenny Root 41c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic const FLAC__byte FLAC__OGG_MAPPING_VERSION_MAJOR = 1; 42c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic const FLAC__byte FLAC__OGG_MAPPING_VERSION_MINOR = 0; 43c74663799493f2b1e6123c18def94295d0afab7Kenny Root 44c74663799493f2b1e6123c18def94295d0afab7Kenny Root/*********************************************************************** 45c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 46c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Public class methods 47c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 48c74663799493f2b1e6123c18def94295d0afab7Kenny Root ***********************************************************************/ 49c74663799493f2b1e6123c18def94295d0afab7Kenny Root 50c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect) 51c74663799493f2b1e6123c18def94295d0afab7Kenny Root{ 52c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* we will determine the serial number later if necessary */ 53c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0) 54c74663799493f2b1e6123c18def94295d0afab7Kenny Root return false; 55c74663799493f2b1e6123c18def94295d0afab7Kenny Root 56c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->seen_magic = false; 57c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->is_first_packet = true; 58c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->samples_written = 0; 59c74663799493f2b1e6123c18def94295d0afab7Kenny Root 60c74663799493f2b1e6123c18def94295d0afab7Kenny Root return true; 61c74663799493f2b1e6123c18def94295d0afab7Kenny Root} 62c74663799493f2b1e6123c18def94295d0afab7Kenny Root 63c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect) 64c74663799493f2b1e6123c18def94295d0afab7Kenny Root{ 65c74663799493f2b1e6123c18def94295d0afab7Kenny Root (void)ogg_stream_clear(&aspect->stream_state); 66c74663799493f2b1e6123c18def94295d0afab7Kenny Root /*@@@ what about the page? */ 67c74663799493f2b1e6123c18def94295d0afab7Kenny Root} 68c74663799493f2b1e6123c18def94295d0afab7Kenny Root 69c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value) 70c74663799493f2b1e6123c18def94295d0afab7Kenny Root{ 71c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->serial_number = value; 72c74663799493f2b1e6123c18def94295d0afab7Kenny Root} 73c74663799493f2b1e6123c18def94295d0afab7Kenny Root 74c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, unsigned value) 75c74663799493f2b1e6123c18def94295d0afab7Kenny Root{ 76c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(value < (1u << FLAC__OGG_MAPPING_NUM_HEADERS_LEN)) { 77c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->num_metadata = value; 78c74663799493f2b1e6123c18def94295d0afab7Kenny Root return true; 79c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 80c74663799493f2b1e6123c18def94295d0afab7Kenny Root else 81c74663799493f2b1e6123c18def94295d0afab7Kenny Root return false; 82c74663799493f2b1e6123c18def94295d0afab7Kenny Root} 83c74663799493f2b1e6123c18def94295d0afab7Kenny Root 84c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect) 85c74663799493f2b1e6123c18def94295d0afab7Kenny Root{ 86c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->serial_number = 0; 87c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->num_metadata = 0; 88c74663799493f2b1e6123c18def94295d0afab7Kenny Root} 89c74663799493f2b1e6123c18def94295d0afab7Kenny Root 90c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* 91c74663799493f2b1e6123c18def94295d0afab7Kenny Root * The basic FLAC -> Ogg mapping goes like this: 92c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 93c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - 'fLaC' magic and STREAMINFO block get combined into the first 94c74663799493f2b1e6123c18def94295d0afab7Kenny Root * packet. The packet is prefixed with 95c74663799493f2b1e6123c18def94295d0afab7Kenny Root * + the one-byte packet type 0x7F 96c74663799493f2b1e6123c18def94295d0afab7Kenny Root * + 'FLAC' magic 97c74663799493f2b1e6123c18def94295d0afab7Kenny Root * + the 2 byte Ogg FLAC mapping version number 98c74663799493f2b1e6123c18def94295d0afab7Kenny Root * + tne 2 byte big-endian # of header packets 99c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - The first packet is flushed to the first page. 100c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Each subsequent metadata block goes into its own packet. 101c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Each metadata packet is flushed to page (this is not required, 102c74663799493f2b1e6123c18def94295d0afab7Kenny Root * the mapping only requires that a flush must occur after all 103c74663799493f2b1e6123c18def94295d0afab7Kenny Root * metadata is written). 104c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Each subsequent FLAC audio frame goes into its own packet. 105c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 106c74663799493f2b1e6123c18def94295d0afab7Kenny Root * WATCHOUT: 107c74663799493f2b1e6123c18def94295d0afab7Kenny Root * This depends on the behavior of FLAC__StreamEncoder that we get a 108c74663799493f2b1e6123c18def94295d0afab7Kenny Root * separate write callback for the fLaC magic, and then separate write 109c74663799493f2b1e6123c18def94295d0afab7Kenny Root * callbacks for each metadata block and audio frame. 110c74663799493f2b1e6123c18def94295d0afab7Kenny Root */ 111c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data) 112c74663799493f2b1e6123c18def94295d0afab7Kenny Root{ 113c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* WATCHOUT: 114c74663799493f2b1e6123c18def94295d0afab7Kenny Root * This depends on the behavior of FLAC__StreamEncoder that 'samples' 115c74663799493f2b1e6123c18def94295d0afab7Kenny Root * will be 0 for metadata writes. 116c74663799493f2b1e6123c18def94295d0afab7Kenny Root */ 117c74663799493f2b1e6123c18def94295d0afab7Kenny Root const FLAC__bool is_metadata = (samples == 0); 118c74663799493f2b1e6123c18def94295d0afab7Kenny Root 119c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* 120c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Treat fLaC magic packet specially. We will note when we see it, then 121c74663799493f2b1e6123c18def94295d0afab7Kenny Root * wait until we get the STREAMINFO and prepend it in that packet 122c74663799493f2b1e6123c18def94295d0afab7Kenny Root */ 123c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(aspect->seen_magic) { 124c74663799493f2b1e6123c18def94295d0afab7Kenny Root ogg_packet packet; 125c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__byte synthetic_first_packet_body[ 126c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH + 127c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__OGG_MAPPING_MAGIC_LENGTH + 128c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH + 129c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH + 130c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH + 131c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__STREAM_SYNC_LENGTH + 132c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__STREAM_METADATA_HEADER_LENGTH + 133c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__STREAM_METADATA_STREAMINFO_LENGTH 134c74663799493f2b1e6123c18def94295d0afab7Kenny Root ]; 135c74663799493f2b1e6123c18def94295d0afab7Kenny Root 136c74663799493f2b1e6123c18def94295d0afab7Kenny Root memset(&packet, 0, sizeof(packet)); 137c74663799493f2b1e6123c18def94295d0afab7Kenny Root packet.granulepos = aspect->samples_written + samples; 138c74663799493f2b1e6123c18def94295d0afab7Kenny Root 139c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(aspect->is_first_packet) { 140c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__byte *b = synthetic_first_packet_body; 141c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) { 142c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* 143c74663799493f2b1e6123c18def94295d0afab7Kenny Root * If we get here, our assumption about the way write callbacks happen 144c74663799493f2b1e6123c18def94295d0afab7Kenny Root * (explained above) is wrong 145c74663799493f2b1e6123c18def94295d0afab7Kenny Root */ 146c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__ASSERT(0); 147c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; 148c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 149c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* add first header packet type */ 150c74663799493f2b1e6123c18def94295d0afab7Kenny Root *b = FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE; 151c74663799493f2b1e6123c18def94295d0afab7Kenny Root b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH; 152c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* add 'FLAC' mapping magic */ 153c74663799493f2b1e6123c18def94295d0afab7Kenny Root memcpy(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH); 154c74663799493f2b1e6123c18def94295d0afab7Kenny Root b += FLAC__OGG_MAPPING_MAGIC_LENGTH; 155c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* add Ogg FLAC mapping major version number */ 156c74663799493f2b1e6123c18def94295d0afab7Kenny Root memcpy(b, &FLAC__OGG_MAPPING_VERSION_MAJOR, FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH); 157c74663799493f2b1e6123c18def94295d0afab7Kenny Root b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH; 158c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* add Ogg FLAC mapping minor version number */ 159c74663799493f2b1e6123c18def94295d0afab7Kenny Root memcpy(b, &FLAC__OGG_MAPPING_VERSION_MINOR, FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH); 160c74663799493f2b1e6123c18def94295d0afab7Kenny Root b += FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH; 161c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* add number of header packets */ 162c74663799493f2b1e6123c18def94295d0afab7Kenny Root *b = (FLAC__byte)(aspect->num_metadata >> 8); 163c74663799493f2b1e6123c18def94295d0afab7Kenny Root b++; 164c74663799493f2b1e6123c18def94295d0afab7Kenny Root *b = (FLAC__byte)(aspect->num_metadata); 165c74663799493f2b1e6123c18def94295d0afab7Kenny Root b++; 166c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* add native FLAC 'fLaC' magic */ 167c74663799493f2b1e6123c18def94295d0afab7Kenny Root memcpy(b, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH); 168c74663799493f2b1e6123c18def94295d0afab7Kenny Root b += FLAC__STREAM_SYNC_LENGTH; 169c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* add STREAMINFO */ 170c74663799493f2b1e6123c18def94295d0afab7Kenny Root memcpy(b, buffer, bytes); 171c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__ASSERT(b + bytes - synthetic_first_packet_body == sizeof(synthetic_first_packet_body)); 172c74663799493f2b1e6123c18def94295d0afab7Kenny Root packet.packet = (unsigned char *)synthetic_first_packet_body; 173c74663799493f2b1e6123c18def94295d0afab7Kenny Root packet.bytes = sizeof(synthetic_first_packet_body); 174c74663799493f2b1e6123c18def94295d0afab7Kenny Root 175c74663799493f2b1e6123c18def94295d0afab7Kenny Root packet.b_o_s = 1; 176c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->is_first_packet = false; 177c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 178c74663799493f2b1e6123c18def94295d0afab7Kenny Root else { 179c74663799493f2b1e6123c18def94295d0afab7Kenny Root packet.packet = (unsigned char *)buffer; 180c74663799493f2b1e6123c18def94295d0afab7Kenny Root packet.bytes = bytes; 181c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 182c74663799493f2b1e6123c18def94295d0afab7Kenny Root 183c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(is_last_block) { 184c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* we used to check: 185c74663799493f2b1e6123c18def94295d0afab7Kenny Root * FLAC__ASSERT(total_samples_estimate == 0 || total_samples_estimate == aspect->samples_written + samples); 186c74663799493f2b1e6123c18def94295d0afab7Kenny Root * but it's really not useful since total_samples_estimate is an estimate and can be inexact 187c74663799493f2b1e6123c18def94295d0afab7Kenny Root */ 188c74663799493f2b1e6123c18def94295d0afab7Kenny Root packet.e_o_s = 1; 189c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 190c74663799493f2b1e6123c18def94295d0afab7Kenny Root 191c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0) 192c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; 193c74663799493f2b1e6123c18def94295d0afab7Kenny Root 194c74663799493f2b1e6123c18def94295d0afab7Kenny Root /*@@@ can't figure out a way to pass a useful number for 'samples' to the write_callback, so we'll just pass 0 */ 195c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(is_metadata) { 196c74663799493f2b1e6123c18def94295d0afab7Kenny Root while(ogg_stream_flush(&aspect->stream_state, &aspect->page) != 0) { 197c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) 198c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; 199c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) 200c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; 201c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 202c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 203c74663799493f2b1e6123c18def94295d0afab7Kenny Root else { 204c74663799493f2b1e6123c18def94295d0afab7Kenny Root while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) { 205c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) 206c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; 207c74663799493f2b1e6123c18def94295d0afab7Kenny Root if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) 208c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; 209c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 210c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 211c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 212c74663799493f2b1e6123c18def94295d0afab7Kenny Root else if(is_metadata && current_frame == 0 && samples == 0 && bytes == 4 && 0 == memcmp(buffer, FLAC__STREAM_SYNC_STRING, sizeof(FLAC__STREAM_SYNC_STRING))) { 213c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->seen_magic = true; 214c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 215c74663799493f2b1e6123c18def94295d0afab7Kenny Root else { 216c74663799493f2b1e6123c18def94295d0afab7Kenny Root /* 217c74663799493f2b1e6123c18def94295d0afab7Kenny Root * If we get here, our assumption about the way write callbacks happen 218c74663799493f2b1e6123c18def94295d0afab7Kenny Root * explained above is wrong 219c74663799493f2b1e6123c18def94295d0afab7Kenny Root */ 220c74663799493f2b1e6123c18def94295d0afab7Kenny Root FLAC__ASSERT(0); 221c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; 222c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 223c74663799493f2b1e6123c18def94295d0afab7Kenny Root 224c74663799493f2b1e6123c18def94295d0afab7Kenny Root aspect->samples_written += samples; 225c74663799493f2b1e6123c18def94295d0afab7Kenny Root 226c74663799493f2b1e6123c18def94295d0afab7Kenny Root return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; 227c74663799493f2b1e6123c18def94295d0afab7Kenny Root} 228