blob: be30d481a2743aafb2cb3a2653025d13aa9c0d19 [file] [log] [blame]
Josh Coalsone9b38b42003-09-26 01:51:44 +00001/* libOggFLAC - Free Lossless Audio Codec + Ogg library
2 * Copyright (C) 2002,2003 Josh Coalson
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of the Xiph.org Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <string.h> /* for memset() */
33#include "FLAC/assert.h"
34#include "private/ogg_encoder_aspect.h"
35
36/***********************************************************************
37 *
38 * Public class methods
39 *
40 ***********************************************************************/
41
42FLAC__bool OggFLAC__ogg_encoder_aspect_init(OggFLAC__OggEncoderAspect *aspect)
43{
44 /* we will determine the serial number later if necessary */
45 if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0)
46 return false;
47
48 aspect->is_first_packet = true;
49 aspect->samples_written = 0;
50
51 return true;
52}
53
54void OggFLAC__ogg_encoder_aspect_finish(OggFLAC__OggEncoderAspect *aspect)
55{
56 (void)ogg_stream_clear(&aspect->stream_state);
57 /*@@@ what aobut the page? */
58}
59
60void OggFLAC__ogg_encoder_aspect_set_serial_number(OggFLAC__OggEncoderAspect *aspect, long value)
61{
62 aspect->serial_number = value;
63}
64
65void OggFLAC__ogg_encoder_aspect_set_defaults(OggFLAC__OggEncoderAspect *aspect)
66{
67 aspect->serial_number = 0;
68}
69
70FLAC__StreamEncoderWriteStatus OggFLAC__ogg_encoder_aspect_write_callback_wrapper(OggFLAC__OggEncoderAspect *aspect, const FLAC__uint64 total_samples_estimate, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, OggFLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data)
71{
72 ogg_packet packet;
73
74 aspect->samples_written += samples;
75
76 memset(&packet, 0, sizeof(packet));
77 packet.packet = (unsigned char *)buffer;
78 packet.granulepos = aspect->samples_written;
79 /* WATCHOUT:
80 * This depends on the behavior of FLAC__StreamEncoder that 'samples'
81 * will be 0 for metadata writes.
82 */
83 packet.packetno = (samples == 0? -1 : (int)current_frame);
84 packet.bytes = bytes;
85
86 if(aspect->is_first_packet) {
87 packet.b_o_s = 1;
88 aspect->is_first_packet = false;
89 }
90
91 if(total_samples_estimate > 0 && total_samples_estimate == aspect->samples_written)
92 packet.e_o_s = 1;
93
94 if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0)
95 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
96
97 while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) {
98 if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
99 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
100
101 if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
102 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
103 }
104
105 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
106}