⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encode.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * --until strings to a number of samples:
	 */
	if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, options.sample_rate, encoder_session.skip, total_samples_in_input))
		return EncoderSession_finish_error(&encoder_session);
	encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
	FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);

	encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
	if(encoder_session.until > 0) {
		const FLAC__uint64 trim = total_samples_in_input - encoder_session.until;
		FLAC__ASSERT(total_samples_in_input > 0);
		FLAC__ASSERT(!options.common.sector_align);
		encoder_session.total_samples_to_encode -= trim;
	}
	if(infilesize >= 0 && options.common.sector_align) {
		FLAC__ASSERT(encoder_session.skip == 0);
		align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
		if(options.common.is_last_file)
			encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
		else
			encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
	}
	encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;

	if(encoder_session.total_samples_to_encode <= 0)
		flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");

	if(encoder_session.skip > 0) {
		unsigned skip_bytes = bytes_per_wide_sample * (unsigned)encoder_session.skip;
		if(skip_bytes > lookahead_length) {
			skip_bytes -= lookahead_length;
			lookahead_length = 0;
			if(!fskip_ahead(infile, skip_bytes)) {
				flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
				return EncoderSession_finish_error(&encoder_session);
			}
		}
		else {
			lookahead += skip_bytes;
			lookahead_length -= skip_bytes;
		}
	}

	if(!EncoderSession_init_encoder(&encoder_session, options.common, options.channels, options.bps, options.sample_rate))
		return EncoderSession_finish_error(&encoder_session);

	/*
	 * first do any samples in the reservoir
	 */
	if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
		if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
			print_error_with_state(&encoder_session, "ERROR during encoding");
			return EncoderSession_finish_error(&encoder_session);
		}
	}

	/*
	 * decrement infilesize if we need to align the file
	 */
	if(options.common.sector_align) {
		FLAC__ASSERT(infilesize >= 0);
		if(options.common.is_last_file) {
			*options.common.align_reservoir_samples = 0;
		}
		else {
			*options.common.align_reservoir_samples = align_remainder;
			infilesize -= (long)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
			FLAC__ASSERT(infilesize >= 0);
		}
	}

	/*
	 * now do from the file
	 */
	if(infilesize < 0) {
		while(!feof(infile)) {
			if(lookahead_length > 0) {
				FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
				memcpy(ucbuffer_, lookahead, lookahead_length);
				bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
				if(ferror(infile)) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
				lookahead_length = 0;
			}
			else
				bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);

			if(bytes_read == 0) {
				if(ferror(infile)) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
			}
			else if(bytes_read % bytes_per_wide_sample != 0) {
				flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
				return EncoderSession_finish_error(&encoder_session);
			}
			else {
				unsigned wide_samples = bytes_read / bytes_per_wide_sample;
				format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);

				if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
					print_error_with_state(&encoder_session, "ERROR during encoding");
					return EncoderSession_finish_error(&encoder_session);
				}
			}
		}
	}
	else {
		const FLAC__uint64 max_input_bytes = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
		FLAC__uint64 total_input_bytes_read = 0;
		while(total_input_bytes_read < max_input_bytes) {
			{
				size_t wanted = (CHUNK_OF_SAMPLES * bytes_per_wide_sample);
				wanted = min(wanted, (size_t)(max_input_bytes - total_input_bytes_read));

				if(lookahead_length > 0) {
					FLAC__ASSERT(lookahead_length <= wanted);
					memcpy(ucbuffer_, lookahead, lookahead_length);
					wanted -= lookahead_length;
					bytes_read = lookahead_length;
					if(wanted > 0) {
						bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
						if(ferror(infile)) {
							flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
							return EncoderSession_finish_error(&encoder_session);
						}
					}
					lookahead_length = 0;
				}
				else
					bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
			}

			if(bytes_read == 0) {
				if(ferror(infile)) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
				else if(feof(infile)) {
					flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
					total_input_bytes_read = max_input_bytes;
				}
			}
			else {
				if(bytes_read % bytes_per_wide_sample != 0) {
					flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
				else {
					unsigned wide_samples = bytes_read / bytes_per_wide_sample;
					format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);

					if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
						print_error_with_state(&encoder_session, "ERROR during encoding");
						return EncoderSession_finish_error(&encoder_session);
					}
					total_input_bytes_read += bytes_read;
				}
			}
		}
	}

	/*
	 * now read unaligned samples into reservoir or pad with zeroes if necessary
	 */
	if(options.common.sector_align) {
		if(options.common.is_last_file) {
			unsigned wide_samples = 588 - align_remainder;
			if(wide_samples < 588) {
				unsigned channel, data_bytes;

				info_align_zero = wide_samples;
				data_bytes = wide_samples * (options.bps >> 3);
				for(channel = 0; channel < options.channels; channel++)
					memset(input_[channel], 0, data_bytes);

				if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
					print_error_with_state(&encoder_session, "ERROR during encoding");
					return EncoderSession_finish_error(&encoder_session);
				}
			}
		}
		else {
			if(*options.common.align_reservoir_samples > 0) {
				FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
				bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
				if(bytes_read == 0 && ferror(infile)) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
				else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
					flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
				}
				else {
					info_align_carry = *options.common.align_reservoir_samples;
					format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, options.is_unsigned_samples, options.channels, options.bps);
				}
			}
		}
	}

	return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
}

FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename)
{
	unsigned i;
	FLAC__uint32 test = 1;

	/*
	 * initialize globals
	 */

	is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;

	for(i = 0; i < FLAC__MAX_CHANNELS; i++)
		input_[i] = &(in_[i][0]);


	/*
	 * initialize instance
	 */

#ifdef FLAC__HAS_OGG
	e->use_ogg = use_ogg;
#else
	(void)use_ogg;
#endif
	e->verify = verify;

	e->is_stdout = (0 == strcmp(outfilename, "-"));

	e->inbasefilename = grabbag__file_get_basename(infilename);
	e->outfilename = outfilename;

	e->skip = 0; /* filled in later after the sample_rate is known */
	e->unencoded_size = 0;
	e->total_samples_to_encode = 0;
	e->bytes_written = 0;
	e->samples_written = 0;
	e->blocksize = 0;
	e->stats_mask = 0;

	e->encoder.flac.stream = 0;
	e->encoder.flac.file = 0;
#ifdef FLAC__HAS_OGG
	e->encoder.ogg.stream = 0;
	e->encoder.ogg.file = 0;
#endif

	e->fin = infile;
	e->fout = 0;
	e->seek_table_template = 0;

	if(e->is_stdout) {
		e->fout = grabbag__file_get_binary_stdout();
	}

	if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
		flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
		return false;
	}

#ifdef FLAC__HAS_OGG
	if(e->use_ogg) {
		if(e->is_stdout) {
			e->encoder.ogg.stream = OggFLAC__stream_encoder_new();
			if(0 == e->encoder.ogg.stream) {
				flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
				EncoderSession_destroy(e);
				return false;
			}
		}
		else {
			e->encoder.ogg.file = OggFLAC__file_encoder_new();
			if(0 == e->encoder.ogg.file) {
				flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
				EncoderSession_destroy(e);
				return false;
			}
		}
	}
	else
#endif
	if(e->is_stdout) {
		e->encoder.flac.stream = FLAC__stream_encoder_new();
		if(0 == e->encoder.flac.stream) {
			flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
			EncoderSession_destroy(e);
			return false;
		}
	}
	else {
		e->encoder.flac.file = FLAC__file_encoder_new();
		if(0 == e->encoder.flac.file) {
			flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
			EncoderSession_destroy(e);
			return false;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -