比尔云BierYun--阿里云最新优惠活动
阿里云优惠码丨阿里云代金券

iOS ijkplayer 数据缓存过程 详解

iOS ijkplayer 数据缓存过程 详解http://www.bieryun.com/2905.html

[objc] view plain copy

  1. ijkplayer buffering过程
  2. static voidvoid *SDL_RunThread(voidvoid *data)
  3. {
  4.     @autoreleasepool {
  5.         SDL_Thread *thread = data;
  6.         pthread_setname_np(thread->name);
  7.         thread->retval = thread->func(thread->data);
  8.         return NULL;
  9.     }
  10. }
  11. //read_thread线程在此处开启
  12. 在read_thread函数内 如果ijkplayer播放器处于缓冲状态ffp->packet_buffering标志位为true
  13.         if (ffp->packet_buffering) {
  14.             io_tick_counter = SDL_GetTickHR();
  15.             if (abs((int)(io_tick_counter – prev_io_tick_counter)) > BUFFERING_CHECK_PER_MILLISECONDS) {
  16.                 prev_io_tick_counter = io_tick_counter;
  17.                 ffp_check_buffering_l(ffp);
  18.             }
  19.         }
  20. ffp_check_buffering_l(ffp);//此处会检查buffering缓冲状态
  21. 在ffp_check_buffering_l函数内会判断收到的未解码数据包个数是否大于最小能播放的数据包大小 当大于最小播放数据包
  22. 并且再判断音视频流的个数和音视频流的请求是否中止 如果都满足条件就修改音视频流的缓冲开关 代码如下:
  23.         if (is->buffer_indicator_queue && is->buffer_indicator_queue->nb_packets > 0) {
  24.             if (   (is->audioq.nb_packets > MIN_MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
  25.                 && (is->videoq.nb_packets > MIN_MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request)) {
  26.                 ffp_toggle_buffering(ffp, 0);//此处关闭缓冲 开始播放
  27.             }
  28.         }
  29. 通过此处可以看出如果想修改ijkplayer的播放缓冲时间和缓冲长度 可以通过修改 MIN_MIN_FRAMES 来实现
  30. #define MIN_MIN_FRAMES      5
  31. void ffp_toggle_buffering(FFPlayer *ffp, int start_buffering)
  32. {
  33.     SDL_LockMutex(ffp->is->play_mutex);
  34.     ffp_toggle_buffering_l(ffp, start_buffering);
  35.     SDL_UnlockMutex(ffp->is->play_mutex);
  36. }
  37. void ffp_toggle_buffering_l(FFPlayer *ffp, int buffering_on)
  38. {
  39.     if (!ffp->packet_buffering)
  40.         return;
  41.     VideoState *is = ffp->is;
  42.     if (buffering_on && !is->buffering_on) {
  43.         av_log(ffp, AV_LOG_DEBUG, “ffp_toggle_buffering_l: start\n”);
  44.         is->buffering_on = 1;
  45.         stream_update_pause_l(ffp);
  46.         ffp_notify_msg1(ffp, FFP_MSG_BUFFERING_START);
  47.     } else if (!buffering_on && is->buffering_on){
  48.         av_log(ffp, AV_LOG_DEBUG, “ffp_toggle_buffering_l: end\n”);
  49.         is->buffering_on = 0;
  50.         stream_update_pause_l(ffp);
  51.         ffp_notify_msg1(ffp, FFP_MSG_BUFFERING_END);
  52.     }
  53. }
  54. static void stream_update_pause_l(FFPlayer *ffp)
  55. {
  56.     VideoState *is = ffp->is;
  57.     if (!is->step && (is->pause_req || is->buffering_on)) {
  58.         stream_toggle_pause_l(ffp, 1);
  59.     } else {
  60.         stream_toggle_pause_l(ffp, 0);
  61.     }
  62. }
  63. /* pause or resume the video */
  64. static void stream_toggle_pause_l(FFPlayer *ffp, int pause_on)
  65. {
  66.     VideoState *is = ffp->is;
  67.     if (is->paused && !pause_on) {
  68.         is->frame_timer += av_gettime_relative() / 1000000.0 – is->vidclk.last_updated;
  69. #ifdef FFP_MERGE
  70.         if (is->read_pause_return != AVERROR(ENOSYS)) {
  71.             is->vidclk.paused = 0;
  72.         }
  73. #endif
  74.         set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
  75.     } else {
  76.     }
  77.     set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
  78.     is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = pause_on;
  79.     SDL_AoutPauseAudio(ffp->aout, pause_on);
  80. }
  81. void SDL_AoutPauseAudio(SDL_Aout *aout, int pause_on)
  82. {
  83.     if (aout && aout->pause_audio)
  84.         aout->pause_audio(aout, pause_on);
  85. }
  86. static void aout_pause_audio(SDL_Aout *aout, int pause_on)
  87. {
  88.     SDLTRACE(“aout_pause_audio(%d)\n”, pause_on);
  89.     SDL_Aout_Opaque *opaque = aout->opaque;
  90.     if (pause_on) {
  91.         [opaque->aoutController pause];
  92.     } else {
  93.         [opaque->aoutController play];
  94.     }
  95. }
  96. – (void)play
  97. {
  98.     if (!_audioQueueRef)
  99.         return;
  100.     self.spec.callback(self.spec.userdataNULL0);
  101.     @synchronized(_lock) {
  102.         _isPaused = NO;
  103.         NSError *error = nil;
  104.         if (NO == [[AVAudioSession sharedInstance] setActive:YES error:&error]) {
  105.             NSLog(@”AudioQueue: AVAudioSession.setActive(YES) failed: %@\n”, error ? [error localizedDescription] : @”nil”);
  106.         }
  107.         OSStatus status = AudioQueueStart(_audioQueueRef, NULL);
  108.         if (status != noErr)
  109.             NSLog(@”AudioQueue: AudioQueueStart failed (%d)\n”, (int)status);
  110.     }
  111. }
  112. 通过以上分析可以看出当通过 ffp_toggle_buffering(ffp, 0);函数修改缓冲状态时中间会通过SDL函数来调用AudioQueue来开始播放

 

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

强烈推荐

高性能SSD云服务器ECS抗攻击,高可用云数据库RDS