2016-07-06 7 views
1

제 목적은 테스트 목적으로 flac 데이터를 디코딩하는 것입니다. 필자는 입력 인수로 데이터와 크기를 취하는 함수를 가진 작은 스텁을 만들 예정입니다. 디코딩 테스트 만하기 때문에 출력 파일을 만들 필요가 없습니다. libflac 페이지 (https://xiph.org/flac/api/)에서 몇 가지 예제와 API 문서를 읽었습니다.C를 사용하여 libFLAC로 데이터 디코딩

이제 오류 코드 : FLAC__stream_decoder_init_stream이 주석 처리되어 있기 때문에 오류 : 초기화 디코더 : (null). 이유는 제대로 사용하고 디코딩 작업을하는 방법을 모른다는 것입니다. 디코딩 작업을하는 데 도움이 될만한 조언이나 의견이 있으십니까?

#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(
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+1

ffmpeg와 같은 스트리밍 프레임 워크에서 작동하도록되어 있으며 모든 것이 이벤트 루프에서 콜백을 사용하여 수행됩니다. - write_callback 및 error_callback 구현은 어디에 있습니까? – Soren

답변

0

당신은 일반적으로 ffmpeg 이루어집니다 것과 유사한 이벤트 처리 프레임 워크를 구현해야을 어디에 FLAC 라이브러리 후크 콜백을 사용한 이벤트 처리. 지금까지 구현 한 것은 흐름 그래프의 (최소한의) 초기화 부분과 비슷하지만 모든 처리 요소가 누락되었습니다.

부끄럽게 그냥 here을 한 일을 다른 사람이보고 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 데이터를 읽는 방법을 살펴보고 지원 기능을 wel로 구현해야합니다 엘.

+0

감사합니다. 나는 콜백 함수를 추가했다. 이제 데이터 인수를 사용하는 방법에 문제가 있습니다. 그것은 무효해야합니다 * client_data하지만 내 함수는 내게 uint8_t을 제공합니다 – Marso

+0

데이터 인수는 실제 flac 데이터가 아니라 콜백 시그니처에 표시되는 'client_data'입니다. 이것은 단지 보조 구성 데이터를 구문 분석하는 방법 일뿐입니다. 귀하의 플러그인 – Soren

+0

답변에 링크 된 예제 코드를주의 깊게 읽으십시오. – Soren