2012-03-21 6 views
8

Używam następującego fragmentu kodu do dekodowania plików audio (testowane z MP3, WAV, WMV).Dekoduje audio za pomocą libavcodec i graj używając libAO?

Ale kiedy odtwarza dźwięk, po prostu wydaje statyczne dźwięki i rozbija się od czasu do czasu. Jakieś wskazówki dotyczące tego, co robię źle tutaj?

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <math.h> 


extern "C" { 
#include "libavutil/mathematics.h" 
#include "libavformat/avformat.h" 
#include "libswscale/swscale.h" 
#include <ao/ao.h> 

} 

void die(const char *msg) 
{ 
    fprintf(stderr,"%s\n",msg); 
    exit(1); 
} 

int main(int argc, char **argv) 
{ 

    const char* input_filename=argv[1]; 

    //avcodec_register_all(); 
    av_register_all(); 
    //av_ini 

    AVFormatContext* container=avformat_alloc_context(); 
    if(avformat_open_input(&container,input_filename,NULL,NULL)<0){ 
     die("Could not open file"); 
    } 

    if(av_find_stream_info(container)<0){ 
     die("Could not find file info"); 
    } 
    av_dump_format(container,0,input_filename,false); 

    int stream_id=-1; 
    int i; 
    for(i=0;i<container->nb_streams;i++){ 
     if(container->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){ 
      stream_id=i; 
      break; 
     } 
    } 
    if(stream_id==-1){ 
     die("Could not find Audio Stream"); 
    } 

    AVDictionary *metadata=container->metadata; 

    AVCodecContext *ctx=container->streams[stream_id]->codec; 
    AVCodec *codec=avcodec_find_decoder(ctx->codec_id); 

    if(codec==NULL){ 
     die("cannot find codec!"); 
    } 

    if(avcodec_open(ctx,codec)<0){ 
     die("Codec cannot be found"); 
    } 

    //ctx=avcodec_alloc_context3(codec); 

    //initialize AO lib 
    ao_initialize(); 

    int driver=ao_default_driver_id(); 

    ao_sample_format sformat; 
    sformat.bits=16; 
    sformat.channels=2; 
    sformat.rate=44100; 
    sformat.byte_format=AO_FMT_NATIVE; 
    sformat.matrix=0; 

    ao_device *adevice=ao_open_live(driver,&sformat,NULL); 
    //end of init AO LIB 

    AVPacket packet; 
    av_init_packet(&packet); 

    AVFrame *frame=avcodec_alloc_frame(); 

    int buffer_size=AVCODEC_MAX_AUDIO_FRAME_SIZE; 
    uint8_t buffer[buffer_size]; 
    packet.data=buffer; 
    packet.size =buffer_size; 



    int len; 
    int frameFinished=0; 
    while(av_read_frame(container,&packet)>=0) 
    { 

     if(packet.stream_index==stream_id){ 
      //printf("Audio Frame read \n"); 
      int len=avcodec_decode_audio4(ctx,frame,&frameFinished,&packet); 
      //frame-> 
      if(frameFinished){ 
       //printf("Finished reading Frame %d %d\n",packet.size,len); 
       ao_play(adevice, (char*)frame->data, len); 
      } 

     } 


    } 

    av_close_input_file(container); 
    ao_shutdown(); 
    return 0; 
} 

Odpowiedz

13

Ok, to kod próbki robocze:

int main(int argc, char **argv) 
{ 

    const char* input_filename=argv[1]; 

    //avcodec_register_all(); 
    av_register_all(); 
    //av_ini 

    AVFormatContext* container=avformat_alloc_context(); 
    if(avformat_open_input(&container,input_filename,NULL,NULL)<0){ 
     die("Could not open file"); 
    } 

    if(av_find_stream_info(container)<0){ 
     die("Could not find file info"); 
    } 
    av_dump_format(container,0,input_filename,false); 

    int stream_id=-1; 
    int i; 
    for(i=0;i<container->nb_streams;i++){ 
     if(container->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){ 
      stream_id=i; 
      break; 
     } 
    } 
    if(stream_id==-1){ 
     die("Could not find Audio Stream"); 
    } 

    AVDictionary *metadata=container->metadata; 

    AVCodecContext *ctx=container->streams[stream_id]->codec; 
    AVCodec *codec=avcodec_find_decoder(ctx->codec_id); 

    if(codec==NULL){ 
     die("cannot find codec!"); 
    } 

    if(avcodec_open(ctx,codec)<0){ 
     die("Codec cannot be found"); 
    } 

    //ctx=avcodec_alloc_context3(codec); 

    //initialize AO lib 
    ao_initialize(); 

    int driver=ao_default_driver_id(); 

    ao_sample_format sformat; 
    AVSampleFormat sfmt=ctx->sample_fmt; 
    if(sfmt==AV_SAMPLE_FMT_U8){ 
     printf("U8\n"); 

     sformat.bits=8; 
    }else if(sfmt==AV_SAMPLE_FMT_S16){ 
     printf("S16\n"); 
     sformat.bits=16; 
    }else if(sfmt==AV_SAMPLE_FMT_S32){ 
     printf("S32\n"); 
     sformat.bits=32; 
    } 

    sformat.channels=ctx->channels; 
    sformat.rate=ctx->sample_rate; 
    sformat.byte_format=AO_FMT_NATIVE; 
    sformat.matrix=0; 

    ao_device *adevice=ao_open_live(driver,&sformat,NULL); 
    //end of init AO LIB 

    AVPacket packet; 
    av_init_packet(&packet); 

    AVFrame *frame=avcodec_alloc_frame(); 



    int buffer_size=AVCODEC_MAX_AUDIO_FRAME_SIZE+ FF_INPUT_BUFFER_PADDING_SIZE;; 
    uint8_t buffer[buffer_size]; 
    packet.data=buffer; 
    packet.size =buffer_size; 



    int len; 
    int frameFinished=0; 
    while(av_read_frame(container,&packet)>=0) 
    { 

     if(packet.stream_index==stream_id){ 
      //printf("Audio Frame read \n"); 
      int len=avcodec_decode_audio4(ctx,frame,&frameFinished,&packet); 
      //frame-> 
      if(frameFinished){ 
       //printf("Finished reading Frame len : %d , nb_samples:%d buffer_size:%d line size: %d \n",len,frame->nb_samples,buffer_size,frame->linesize[0]); 
       ao_play(adevice, (char*)frame->extended_data[0],frame->linesize[0]); 
      }else{ 
       //printf("Not Finished\n"); 
      } 

     }else { 
      printf("Someother packet possibly Video\n"); 
     } 


    } 

    av_close_input_file(container); 
    ao_shutdown(); 
    return 0; 
} 
+3

I dodaje płaska podstawa akustycznego, który to kod jest tutaj http://0xdeafc0de.wordpress.com/2013/12/19/ffmpeg- audio-playback-sample/ –

+0

@MaduraAnushanga oh też jesteś z sri lanki :) –

+0

Tak, jestem :) Ty też jesteś? Twoje nazwisko brzmi dziwnie ... –

Powiązane problemy