stream_component_open

来源:互联网 发布:原子车车架数据 编辑:程序博客网 时间:2024/06/08 07:42
转自http://blog.csdn.net/mydeardingxiaoli/article/details/17224629

1、主要步骤
  1. static int stream_component_open(VideoState *is, int stream_index)  
  2. {  
  3.     //依照编解码上下文的codec_id,遍历编解码器链表,找到相应的解码器  
  4.     codec = avcodec_find_decoder(enc->codec_id);  
  5.   
  6.     //打开编解码器,初始化具体编解码器的运行环境。  
  7.     if (!codec || avcodec_open(enc, codec) < 0)  
  8.         return -1;  
  9.   
  10.     switch(enc->codec_type)   
  11.     {  
  12.     /* prepare audio  */  
  13.     case CODEC_TYPE_AUDIO:  
  14.         //初始化音频队列  
  15.         packet_queue_init(&is->audioq);  
  16.   
  17.         //启动广义的音频解码线程。  
  18.         wanted_spec.callback = sdl_audio_callback;  
  19.         wanted_spec.userdata = is;  
  20.         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {  
  21.             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());  
  22.             return -1;  
  23.         }  
  24.         SDL_PauseAudio(0);  
  25.         break;  
  26.   
  27.     case CODEC_TYPE_VIDEO:  
  28.         //初始化视频队列  
  29.         packet_queue_init(&is->videoq);  
  30.          //启动视频解码线程  
  31.         is->video_tid = SDL_CreateThread(video_thread, is);  
  32.         break;  
  33.   
  34.     case CODEC_TYPE_SUBTITLE:  
  35.         packet_queue_init(&is->subtitleq);  
  36.         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);  
  37.         break;  
  38.     default:  
  39.         break;  
  40.     }  
  41.     return 0;  
  42. }  



2、具体代码(解码线程)

  1. static int stream_component_open(VideoState *isint stream_index)  
  2. {  
  3.     AVFormatContext *ic = is->ic;  
  4.     AVCodecContext *enc;  
  5.     AVCodec *codec;  
  6.     <strong>SDL_AudioSpec wanted_spec, spec;</strong>  
  7.   
  8.     if (stream_index < 0 || stream_index >= ic->nb_streams)  
  9.         return -1;  
  10.     enc = ic->streams[stream_index]->codec;  
  11.   
  12.     /* prepare audio output */  
  13.     if (enc->codec_type == CODEC_TYPE_AUDIO) {   //如果为音频解码,需要初始化参数  
  14.         if (enc->channels > 0) {  
  15.             enc->request_channels = FFMIN(2, enc->channels);  
  16.         } else {  
  17.             enc->request_channels = 2;  
  18.         }  
  19.     }  
  20.   
  21.     codec = avcodec_find_decoder(enc->codec_id);  //根据id找到具体的解码器  
  22.     enc->debug_mv = debug_mv;  
  23.     enc->debug = debug;  
  24.     enc->workaround_bugs = workaround_bugs;  
  25.     enc->lowres = lowres;  
  26.     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;  
  27.     enc->idct_algo= idct;  
  28.     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;  
  29.     enc->skip_frame= skip_frame;  
  30.     enc->skip_idct= skip_idct;  
  31.     enc->skip_loop_filter= skip_loop_filter;  
  32.     enc->error_recognition= error_recognition;  
  33.     enc->error_concealment= error_concealment;  
  34.   
  35.     set_context_opts(enc, avctx_opts[enc->codec_type], 0); //set  decode  option  
  36.   
  37.     if (!codec ||  
  38.         avcodec_open(enc, codec) < 0) //open decode  
  39.         return -1;  
  40.   
  41.     /* prepare audio output */  
  42.     if (enc->codec_type == CODEC_TYPE_AUDIO) {  
  43.         wanted_spec.freq = enc->sample_rate;  
  44.         wanted_spec.format = AUDIO_S16SYS;  
  45.         wanted_spec.channels = enc->channels;  
  46.         wanted_spec.silence = 0;  
  47.         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;  
  48.         wanted_spec.callback = <strong><span style="color:#ff0000;">sdl_audio_callback</span></strong>; //此处初始化了一个音频解码线程(线程是在SDL中实现的,此接口是对用户提供了一个回调函数接口)  
  49.         wanted_spec.userdata = is;  
  50.         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {  
  51.             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());  
  52.             return -1;  
  53.         }  
  54.         is->audio_hw_buf_size = spec.size;  
  55.         is->audio_src_fmt= SAMPLE_FMT_S16;  
  56.     }  
  57.   
  58.     if(thread_count>1)  
  59.         avcodec_thread_init(enc, thread_count);  //解码线程初始化  
  60.     enc->thread_count= thread_count;  
  61.     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;  
  62.     switch(enc->codec_type) {  
  63.     case CODEC_TYPE_AUDIO:  
  64.         is->audio_stream = stream_index;  
  65.         is->audio_st = ic->streams[stream_index];  
  66.         is->audio_buf_size = 0;  
  67.         is->audio_buf_index = 0;  
  68.   
  69.         /* init averaging filter */  
  70.         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);  
  71.         is->audio_diff_avg_count = 0;  
  72.         /* since we do not have a precise anough audio fifo fullness, 
  73.            we correct audio sync only if larger than this threshold */  
  74.         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;  
  75.   
  76.         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));  
  77.         packet_queue_init(&is->audioq);  
  78.         SDL_PauseAudio(0);  
  79.         break;  
  80.     case CODEC_TYPE_VIDEO:  
  81.         is->video_stream = stream_index;  
  82.         is->video_st = ic->streams[stream_index];  
  83.   
  84.         is->frame_last_delay = 40e-3;  
  85.         is->frame_timer = (double)av_gettime() / 1000000.0;  
  86.         is->video_current_pts_time = av_gettime();  
  87.   
  88.         packet_queue_init(&is->videoq);  
  89.         is->video_tid = SDL_CreateThread(video_thread, is); //如果为视频,则创建一个视频处理线程  
  90.         break;  
  91.     case CODEC_TYPE_SUBTITLE:  
  92.         is->subtitle_stream = stream_index;  
  93.         is->subtitle_st = ic->streams[stream_index];  
  94.         packet_queue_init(&is->subtitleq);  
  95.   
  96.         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);  
  97.         break;  
  98.     default:  
  99.         break;  
  100.     }  
  101.     return 0;  
  102. }  

0 0
原创粉丝点击