使用 C 使用 libFLAC 解码数据
Decoding data with libFLAC using C
我的目的是为了测试目的解码 flac 数据。我将创建一个小存根,它具有一个将数据和大小作为输入参数的函数。不需要制作任何类型的输出文件,因为我只打算进行解码测试。我已经从 libflac 页面 (https://xiph.org/flac/api/) 中阅读了一些示例和 api 文档。
现在这是给我:错误:初始化解码器:(空)因为 FLAC__stream_decoder_init_stream 被评论了。评论的原因是我不知道如何正确使用它并进行解码工作。有什么建议和意见可以帮助我完成解码工作吗?
#include <stdio.h>
#include <stdlib.h>
#include "share/compat.h"
#include "FLAC/stream_decoder.h"
static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *data);
static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *data);
static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *data);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FLAC__bool ok = true;
FLAC__StreamDecoder *decoder = 0;
FLAC__StreamDecoderInitStatus init_status;
// init decoder
if((decoder = FLAC__stream_decoder_new()) == NULL) {
fprintf(stderr, "ERROR: allocating decoder\n");
return 1;
}
(void)FLAC__stream_decoder_set_md5_checking(decoder, true);
init_status = FLAC__stream_decoder_init_stream ( decoder, read_callback, /*seek_callback*/ NULL, /*tell_callback*/ NULL, /*length_callback*/ NULL, /*eof_callback*/ NULL, write_callback, /*metadata_callback*/ NULL, error_callback, data);
if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
fprintf(stderr, "ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
ok = false;
}
if(ok) {
ok = FLAC__stream_decoder_process_until_end_of_stream(decoder);
fprintf(stderr, "decoding: %s\n", ok? "succeeded" : "FAILED");
fprintf(stderr, " state: %s\n", FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(decoder)]);
}
FLAC__stream_decoder_delete(decoder);
return 0;
}
void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *data)
{
(void)decoder, (void)data;
fprintf(stderr, "Got error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
}
更新:
添加回调函数后出现此错误:
flac_fuzzer.c:23:16: error: no matching function for call to 'FLAC__stream_decoder_init_stream'
init_status = FLAC__stream_decoder_init_stream ( decoder,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/FLAC/stream_decoder.h:1073:40: note: candidate function not viable: no known conversion from 'const uint8_t *'
(aka 'const unsigned char *') to 'void *' for 10th argument; take the address of the argument with &
FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
您通常需要实施一个事件处理框架,类似于 ffmpeg 所做的,其中 flac 库使用回调挂钩到事件处理中。到目前为止您实现的内容看起来像是流程图的(最小)初始化部分,但您缺少所有处理元素。
可耻地看看别人做了什么 here and here 你将需要使用
这样的签名来实现回调函数
编写回调示例:
static FLAC__StreamDecoderWriteStatus flac_write_music_cb(
const FLAC__StreamDecoder *decoder,
const FLAC__Frame *frame,
const FLAC__int32 *const buffer[],
void *client_data)
错误回调示例:
static void flac_error_music_cb(
const FLAC__StreamDecoder *decoder,
FLAC__StreamDecoderErrorStatus status,
void *client_data)
你还应该看看flac数据是如何读取的,并实现配套的功能。
既然你使用了extern "C"
,那你肯定是把它编译成C++代码了。现在,在 C++ 中,您需要使用 const_cast<>
来传递 const uint8_t*
参数,其中需要非常量参数(即 void*
)。
我的目的是为了测试目的解码 flac 数据。我将创建一个小存根,它具有一个将数据和大小作为输入参数的函数。不需要制作任何类型的输出文件,因为我只打算进行解码测试。我已经从 libflac 页面 (https://xiph.org/flac/api/) 中阅读了一些示例和 api 文档。
现在这是给我:错误:初始化解码器:(空)因为 FLAC__stream_decoder_init_stream 被评论了。评论的原因是我不知道如何正确使用它并进行解码工作。有什么建议和意见可以帮助我完成解码工作吗?
#include <stdio.h>
#include <stdlib.h>
#include "share/compat.h"
#include "FLAC/stream_decoder.h"
static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *data);
static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *data);
static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *data);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FLAC__bool ok = true;
FLAC__StreamDecoder *decoder = 0;
FLAC__StreamDecoderInitStatus init_status;
// init decoder
if((decoder = FLAC__stream_decoder_new()) == NULL) {
fprintf(stderr, "ERROR: allocating decoder\n");
return 1;
}
(void)FLAC__stream_decoder_set_md5_checking(decoder, true);
init_status = FLAC__stream_decoder_init_stream ( decoder, read_callback, /*seek_callback*/ NULL, /*tell_callback*/ NULL, /*length_callback*/ NULL, /*eof_callback*/ NULL, write_callback, /*metadata_callback*/ NULL, error_callback, data);
if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
fprintf(stderr, "ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
ok = false;
}
if(ok) {
ok = FLAC__stream_decoder_process_until_end_of_stream(decoder);
fprintf(stderr, "decoding: %s\n", ok? "succeeded" : "FAILED");
fprintf(stderr, " state: %s\n", FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(decoder)]);
}
FLAC__stream_decoder_delete(decoder);
return 0;
}
void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *data)
{
(void)decoder, (void)data;
fprintf(stderr, "Got error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
}
更新: 添加回调函数后出现此错误:
flac_fuzzer.c:23:16: error: no matching function for call to 'FLAC__stream_decoder_init_stream'
init_status = FLAC__stream_decoder_init_stream ( decoder,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/FLAC/stream_decoder.h:1073:40: note: candidate function not viable: no known conversion from 'const uint8_t *'
(aka 'const unsigned char *') to 'void *' for 10th argument; take the address of the argument with &
FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
您通常需要实施一个事件处理框架,类似于 ffmpeg 所做的,其中 flac 库使用回调挂钩到事件处理中。到目前为止您实现的内容看起来像是流程图的(最小)初始化部分,但您缺少所有处理元素。
可耻地看看别人做了什么 here and here 你将需要使用
这样的签名来实现回调函数编写回调示例:
static FLAC__StreamDecoderWriteStatus flac_write_music_cb(
const FLAC__StreamDecoder *decoder,
const FLAC__Frame *frame,
const FLAC__int32 *const buffer[],
void *client_data)
错误回调示例:
static void flac_error_music_cb(
const FLAC__StreamDecoder *decoder,
FLAC__StreamDecoderErrorStatus status,
void *client_data)
你还应该看看flac数据是如何读取的,并实现配套的功能。
既然你使用了extern "C"
,那你肯定是把它编译成C++代码了。现在,在 C++ 中,您需要使用 const_cast<>
来传递 const uint8_t*
参数,其中需要非常量参数(即 void*
)。