2014-12-08 4 views
0

현재, 항상 오류를 반환하는 avcodec_decode_audio4()를 사용하여 오디오 디코딩을 처음 시도하고 있습니다.libavcodec avcodec_decode_audio4를 사용한 오디오 디코딩 오류

참고 : 전체적인 의도는 여러 개의 AMR_NB 인코딩 파일을 하나의 오디오 파일로 병합 한 다음 최종 오디오 파일을 다른 비디오 파일과 .mp4 컨테이너로 혼합하는 것입니다. 여기

if(avformat_open_input(&sound, "/tmp/aud0", NULL, NULL)!=0) {             
     printf("Error in opening input file aud0\n"); 
     exit(1); 
    } else { 
     printf("Opened aud0 into FormatContext\n"); 
    } 

    if(avformat_find_stream_info(sound, NULL)<0){ 
     printf("Error in finding stream info\n"); 
     avformat_close_input(&sound); 
     exit(1); 
    } 

    int aud_stream_idx=-1; 
    for(int count=0; count<sound->nb_streams; count++) { 
     if(sound->streams[count]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { 
     aud_stream_idx = count;   
     printf("Audio stream index %d found\n", count); 
     break; 
     } 
    } 
    if(aud_stream_idx==-1) { 
     printf("Audio stream not found in the aud0 file\n"); 
     avformat_close_input(&sound); 
     exit(1); 
    } 

    AVCodecContext *audioCC = sound->streams[aud_stream_idx]->codec; 
    printf("Audio codec_id=%d, codec_name=%s\n", audioCC->codec_id, audioCC->codec_name); 

    AVCodec *audioC = avcodec_find_decoder(audioCC->codec_id); 
    if (audioC == NULL) {  printf("Couldn't find decoder\n"); 
     avformat_close_input(&sound); 
     exit(1); 
    } else { 
     printf("Found decoder name %s\n", audioCC->codec_name); 
    } 

    if(avcodec_open2(audioCC, audioC, NULL)<0) { 
     printf("Couldn't open decoder\n"); 
     avformat_close_input(&sound); 
     exit(1); 
    } else { 
     printf("Found decoder name %s\n", audioCC->codec_name); 
     printf("Found bitrate %d\n", audioCC->bit_rate); 
     printf("Found sample_rate %d\n", audioCC->sample_rate); 
     printf("Found sample_fmt %d\n", audioCC->sample_fmt); } 

    /* decode until eof */ 
    av_init_packet(&avpkt); 
    avpkt.data=NULL; 
    avpkt.size=0; 
    if(av_read_frame(sound, &avpkt)<0) { 
     printf("Couldn't read encoded audio packet\n"); 
     av_free_packet(&avpkt); 
     avformat_close_input(&sound); 
     exit(1); 
    } else { 
     printf("Read encoded audio packet\n"); 
     printf("avpkt.pts = %d\n", avpkt.pts); 
     printf("avpkt.dts = %d\n", avpkt.dts); 
     printf("avpkt.duration = %d\n", avpkt.duration);  
     printf("avpkt.stream_index = %d\n", avpkt.stream_index); 
     printf("avpkt.data = %x\n", avpkt.data); 
     printf("avpkt.data[0] = %02x\n", avpkt.data[0]); 
     printf("avpkt.data[0]>>>3&0x0f = %02x\n", avpkt.data[0]>>3 & 0x0f); 
    } 

    fprintf(stderr, "avpkt.size=%d\n", avpkt.size); 
    while (avpkt.size > 0) { 
     int got_frame = 0; 

     if (!decoded_frame) { 
      if (!(decoded_frame = avcodec_alloc_frame())) { 
       fprintf(stderr, "out of memory\n"); 
       exit(1); 
      }  } else 
      avcodec_get_frame_defaults(decoded_frame); 


     len = avcodec_decode_audio4(audioCC, decoded_frame, &got_frame, &avpkt); 
     if (len < 0) { 
      fprintf(stderr, "Error %d while decoding\n", len); 
      exit(1); 
     } 

을 나는 (내가 잘 작동 디 먹싱 생각)을 참조 출력 :

여기에 코드의이 오디오는 안드로이드 장치에 음성을 녹음하여 만든

Opened aud0 into FormatContext 
Audio stream index 0 found 
Audio codec_id=73728, codec_name= 
Found decoder name 
Found decoder name 
Found bitrate 5200 
Found sample_rate 8000 
Found sample_fmt 3 
Read encoded audio packet 
avpkt.pts = 0 
avpkt.dts = 0 
avpkt.duration = 160 
avpkt.stream_index = 0 
avpkt.data = 91e00680 
avpkt.data[0] = 04 
avpkt.data[0]>>>3&0x0f = 00 
avpkt.size=13 
[amrnb @ 0x7fce9300bc00] Corrupt bitstream 
Error -1094995529 while decoding 

.

또한 QuickTime에서 생성 된 .m4a를 시도했지만 운이 없었습니다.

일부 중요한 단계 (일부 CodecContext 필드를 초기화하지 않거나 AVPacket을 제대로 읽지 않는 것)가 누락되었습니다. 어떤 경우라도 다른 사람이 입력하거나 유사한 예가 있으면 알려 주시기 바랍니다.

답변

0

먼저 EOF에 도달 할 때까지 av_read_frame을 호출해야합니다. 따라서 루프에서 av_read_frame이 필요합니다.

디코딩 작동 방식을 설명하겠습니다.
formatcontext, codeccontext 및 decoder를 엽니 다. 그것은 쉬운 부분입니다.
루프에서 패킷을 하나의 스트림으로 읽습니다. 그래서 당신은 패킷에서 데이터를 해독하고자하는이 루프에서

while(av_read_frame(sound, &avpkt)) 

이 필요합니다. 그러나 신경 써서, 패킷의 데이터가 어떤 스트림인지 확인해야합니다. 패킷에 오디오 스트림의 데이터가 포함되어 있는지 항상 확인하는 것이 좋습니다.

if (avpkt.stream_index == aud_stream_idx) 

이제 오디오를 디코딩하고 처리 할 수 ​​있습니다.

exmaple :

AVFrame * decoded_frame = av_frame_alloc(); 
AVPacket avpkt; 
av_init_packet(&avpkt); 
avpkt.data = NULL; 
avpkt.size = 0; 
while(av_read_frame(sound, &avpkt)) 
{ 
    if (avpkt.stream_index == aud_stream_idx) 
    { 
     int got_frame; 
     int len = avcodec_decode_audio4(audioCC, decoded_frame, &got_frame, &avpkt); 
    } 
} 

그게 모든 마법 :

PS : 스트림을 찾을 단지

av_find_best_stream(sound, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0) 

PPS를 호출 코드를 테스트하지 않았다. 여기에 코덱이 있습니다 : D
PPPS : 예제를 읽으십시오. this 나를 많이 도왔습니다.

1

다른 사람들이 ffmpeg 오류 코드를 이해할 수 있도록 도움이 될 수 있습니다. 는 FFmpeg에서 오류 코드 (avutil에서 error.h는) : http://ffmpeg.org/doxygen/trunk/error_8h_source.html

그것은 당신이 지정한 값이 밝혀 :

#define AVERROR_INVALIDDATA  FFERRTAG('I','N','D','A') 

당신이 그 편지를 볼 때 -1094995529가 ACSII에, -0x41444E49되고 , 0x41 = 'A', 0x44 = 'D', 0x4E = 'N, 0x49 ='I '. 매크로/etc로 인해 ADNI가 #define 스 니펫에서 볼 수있는 INDA가되고 FERRTAG ('I', 'N', 'D', 'A')로 정의 된 AVERROR_INVALIDDATA가됩니다.

오류 코드의 나머지 부분은 해당 파일에 있고 나는 아래에 여기를 붙여 넣은 :

#define AVERROR_BSF_NOT_FOUND  FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found 
#define AVERROR_BUG    FFERRTAG('B','U','G','!') ///< Internal bug, also see AVERROR_BUG2 
#define AVERROR_BUFFER_TOO_SMALL FFERRTAG('B','U','F','S') ///< Buffer too small 
#define AVERROR_DECODER_NOT_FOUND FFERRTAG(0xF8,'D','E','C') ///< Decoder not found 
#define AVERROR_DEMUXER_NOT_FOUND FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found 
#define AVERROR_ENCODER_NOT_FOUND FFERRTAG(0xF8,'E','N','C') ///< Encoder not found 
#define AVERROR_EOF    FFERRTAG('E','O','F',' ') ///< End of file 
#define AVERROR_EXIT    FFERRTAG('E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted 
#define AVERROR_EXTERNAL   FFERRTAG('E','X','T',' ') ///< Generic error in an external library 
#define AVERROR_FILTER_NOT_FOUND FFERRTAG(0xF8,'F','I','L') ///< Filter not found 
#define AVERROR_INVALIDDATA  FFERRTAG('I','N','D','A') ///< Invalid data found when processing input 
#define AVERROR_MUXER_NOT_FOUND FFERRTAG(0xF8,'M','U','X') ///< Muxer not found 
#define AVERROR_OPTION_NOT_FOUND FFERRTAG(0xF8,'O','P','T') ///< Option not found 
#define AVERROR_PATCHWELCOME  FFERRTAG('P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome 
#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found 
#define AVERROR_STREAM_NOT_FOUND FFERRTAG(0xF8,'S','T','R') ///< Stream not found 
#define AVERROR_BUG2    FFERRTAG('B','U','G',' ') 
#define AVERROR_UNKNOWN   FFERRTAG('U','N','K','N') ///< Unknown error, typically from an external library 
#define AVERROR_EXPERIMENTAL  (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it. 
#define AVERROR_INPUT_CHANGED  (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED) 
#define AVERROR_OUTPUT_CHANGED  (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED) 
#define AVERROR_HTTP_BAD_REQUEST FFERRTAG(0xF8,'4','0','0') 
#define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') 
#define AVERROR_HTTP_FORBIDDEN  FFERRTAG(0xF8,'4','0','3') 
#define AVERROR_HTTP_NOT_FOUND  FFERRTAG(0xF8,'4','0','4') 
#define AVERROR_HTTP_OTHER_4XX  FFERRTAG(0xF8,'4','X','X') 
#define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X')