ffplay注解

  1. /* 
  2. get_clock(&is->vidclk): 
  3.     获取到的实际上是:最后一帧的pts 加上 从处理最后一帧开始到现在的时间,具体参考set_clock_at 和get_clock的代码 
  4. c->pts_drift=最后一帧的pts-从处理最后一帧时间 
  5. clock=c->pts_drift+现在的时候 
  6. get_clock(&is->vidclk) ==is->vidclk.pts, av_gettime_relative() / 1000000.0 -is->vidclk.last_updated  +is->vidclk.pts 
  7. */  
  8. static double get_clock(Clock *c)  
  9. {  
  10.     if (*c->queue_serial != c->serial)  
  11.         return NAN;  
  12.     if (c->paused) {  
  13.         return c->pts;  
  14.     } else {  
  15.         double time = av_gettime_relative() / 1000000.0;  
  16.         return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);  
  17.     }  
  18. }  
  19.   
  20. static void set_clock_at(Clock *c, double pts, int serial, double time)  
  21. {  
  22.     c->pts = pts;  
  23.     c->last_updated = time;  
  24.     c->pts_drift = c->pts - time;  
  25.     c->serial = serial;  
  26. }  
  27.   
  28. static void set_clock(Clock *c, double pts, int serial)  
  29. {  
  30.     double time = av_gettime_relative() / 1000000.0;  
  31.     set_clock_at(c, pts, serial, time);  
  32. }  
  33.   
  34. static void set_clock_speed(Clock *c, double speed)  
  35. {  
  36.     set_clock(c, get_clock(c), c->serial);  
  37.     c->speed = speed;  
  38. }  
  39.   
  40. static void init_clock(Clock *c, int *queue_serial)  
  41. {  
  42.     c->speed = 1.0;  
  43.     c->paused = 0;  
  44.     c->queue_serial = queue_serial;  
  45.     set_clock(c, NAN, -1);  
  46. }  
  47.   
  48. static void sync_clock_to_slave(Clock *c, Clock *slave)  
  49. {  
  50.     double clock = get_clock(c);  
  51.     double slave_clock = get_clock(slave);  
  52.       
  53.     if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))  
  54.         set_clock(c, slave_clock, slave->serial);  
  55. }  
  56.   
  57. /* get the current master clock value */  
  58. static double get_master_clock(VideoState *is)  
  59. {  
  60.     double val;  
  61.   
  62.     switch (get_master_sync_type(is)) {  
  63.     case AV_SYNC_VIDEO_MASTER:  
  64.         val = get_clock(&is->vidclk);  
  65.         break;  
  66.     case AV_SYNC_AUDIO_MASTER:  
  67.         val = get_clock(&is->audclk);  
  68.         break;  
  69.     default:  
  70.         val = get_clock(&is->extclk);  
  71.         break;  
  72.     }  
  73.     return val;  
  74. }  
  75.   
  76. static void check_external_clock_speed(VideoState *is)  
  77. {  
  78.     if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||  
  79.         is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {  
  80.         set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));  
  81.     } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&  
  82.                (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {  
  83.         set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));  
  84.     } else {  
  85.         double speed = is->extclk.speed;  
  86.         if (speed != 1.0)  
  87.             set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));  
  88.     }  
  89. }  
  90.   
  91. static double compute_target_delay(double delay, VideoState *is)  
  92. {  
  93.     double sync_threshold, diff = 0;  
  94.   
  95.     /* update delay to follow master synchronisation source */  
  96.     if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {  
  97.         /* if video is slave, we try to correct big delays by 
  98.            duplicating or deleting a frame */  
  99.         diff = get_clock(&is->vidclk) - get_master_clock(is);  
  100.   
  101.         /* skip or repeat frame. We take into account the 
  102.            delay to compute the threshold. I still don't know 
  103.            if it is the best guess */  
  104.         sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));  
  105.         if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {  
  106.             if (diff <= -sync_threshold)  )/*当前视频帧落后于主时钟源,减小delay*/  
  107.                 delay = FFMAX(0, delay + diff);  
  108.             else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)  
  109.                 delay = delay + diff; /*大概意思是:本来当视频帧超前的时候, 
  110.                                         我们应该要选择重复该帧或者下面的2倍延时(即加重延时的策略), 
  111.                                         但因为该帧的显示时间大于显示更新门槛, 
  112.                                         所以这个时候不应该以该帧做同步*/  
  113.             else if (diff >= sync_threshold)  
  114.                 delay = 2 * delay;    /*采取加倍延时*/  
  115.         }  
  116.     }  
  117.   
  118.     av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",  
  119.            delay, -diff);  
  120.   
  121.     return delay;  
  122. }  
  123.   
  124. static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp)  
  125. {  
  126.     if (vp->serial == nextvp->serial) {  
  127.         double duration = nextvp->pts - vp->pts;  
  128.         if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)  
  129.             return vp->duration;  
  130.         else  
  131.             return duration;  
  132.     } else {  
  133.         return 0.0;  
  134.     }  
  135. }  
  136.   
  137. static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial)  
  138. {  
  139.     /* update current video pts */  
  140.     set_clock(&is->vidclk, pts, serial);  
  141.     sync_clock_to_slave(&is->extclk, &is->vidclk);  
  142. }  
  143.   
  144. /* called to display each frame */  
  145. static void video_refresh(void *opaque, double *remaining_time)  
  146. {  
  147.     VideoState *is = opaque;  
  148.     double time;  
  149.   
  150.     if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)  
  151.         check_external_clock_speed(is);  
  152.   
  153.     if (is->video_st) {  
  154.         int redisplay = 0;  
  155.         if (is->force_refresh)  
  156.             redisplay = frame_queue_prev(&is->pictq);  
  157. retry:  
  158.         if (frame_queue_nb_remaining(&is->pictq) == 0) {  
  159.             // nothing to do, no picture to display in the queue  
  160.         } else {  
  161.             double last_duration, duration, delay;  
  162.             Frame *vp, *lastvp;  
  163.   
  164.             /* dequeue the picture */  
  165.             lastvp = frame_queue_peek_last(&is->pictq);  
  166.             vp = frame_queue_peek(&is->pictq);  
  167.   
  168.             if (vp->serial != is->videoq.serial) {  
  169.                 frame_queue_next(&is->pictq);  
  170.                 redisplay = 0;  
  171.                 goto retry;  
  172.             }  
  173.   
  174.             if (lastvp->serial != vp->serial && !redisplay)  //lastvp->serial != vp->serial 说明SEEK过,重新调整frame_timer  
  175.                 is->frame_timer = av_gettime_relative() / 1000000.0;  
  176.   
  177.             if (is->paused)  
  178.                 goto display;  
  179.   
  180.             /*通过pts计算duration,duration是上一帧videoframe的持续时间,当前帧的pts减去上一帧的pts*/  
  181.             /* compute nominal last_duration */  
  182.             last_duration = vp_duration(is, lastvp, vp);  
  183.             if (redisplay)  
  184.                 delay = 0.0;  
  185.             else  
  186.                 delay = compute_target_delay(last_duration, is);  
  187.   
  188.             time= av_gettime_relative()/1000000.0;  
  189.             /*frame_timer实际上就是上一帧的播放时间,而 frame_timer + delay 实际上就是当前这一帧的播放时间*/  
  190.             if (time < is->frame_timer + delay && !redisplay) {  
  191.                 /*remaining 就是在refresh_loop_wait_event 中还需要睡眠的时间,其实就是现在还没到这一帧的播放时间,我们需要睡眠等待*/  
  192.                 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);  
  193.                 return;  
  194.             }  
  195.   
  196.             is->frame_timer += delay;  
  197.             /*如果当前这一帧播放时间已经过了,并且其和当前系统时间的差值超过AV_SYNC_THRESHOLD_MAX, 
  198.                 则将当前这一帧的播放时间改为当前系统时间,并在后续判断是否需要丢帧, 
  199.                 其目的是  为后面帧的播放时间重新调整frame_timer */  
  200.             if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)  
  201.                 is->frame_timer = time;  
  202.   
  203.             SDL_LockMutex(is->pictq.mutex);  
  204.             if (!redisplay && !isnan(vp->pts))  
  205.                 /*更新视频的clock,将当前帧的pts和当前系统的时间保存起来,这2个数据将和audio  clock的pts 和系统时间一起计算delay*/  
  206.                 update_video_pts(is, vp->pts, vp->pos, vp->serial);  
  207.             SDL_UnlockMutex(is->pictq.mutex);  
  208.             /*frame_timer+duration 当前帧的播放时间+当前帧的持续时间=下一帧的播放时间 
  209.             time > is->frame_timer + duration  当前时间>下一帧的播放时间,来不及播放本帧,下一帧的播放时间已经到了,说明当前帧可以丢弃了*/  
  210.             if (frame_queue_nb_remaining(&is->pictq) > 1) {  
  211.                 Frame *nextvp = frame_queue_peek_next(&is->pictq);  
  212.                 duration = vp_duration(is, vp, nextvp); //当前帧videoframe的持续时间  
  213.                 /*如果延迟时间超过一帧,并且允许丢帧,则进行丢帧处理*/  
  214.                 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration) {  
  215.                     if (!redisplay)  
  216.                         is->frame_drops_late++;  
  217.                     /*丢掉延迟的帧,取下一帧*/  
  218.                     frame_queue_next(&is->pictq);  
  219.                     redisplay = 0;  
  220.                     goto retry;  
  221.                 }  
  222.             }  
  223. display:  
  224.             /* display picture */  
  225.             video_display(is);  
  226.   
  227.             frame_queue_next(&is->pictq);  
  228.   
  229.             if (is->step && !is->paused)  
  230.                 stream_toggle_pause(is);  
  231.         }  
  232.     }  
  233.     is->force_refresh = 0;  
  234. }  
  235.   
  236. static int audio_thread(void *arg)  
  237. {  
  238.     VideoState *is = arg;  
  239.     AVFrame *frame = av_frame_alloc();  
  240.     Frame *af;  
  241.   
  242.     int got_frame = 0;  
  243.     AVRational tb;  
  244.     int ret = 0;  
  245.   
  246.     do {  
  247.         if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)  
  248.                 goto the_end;  
  249.   
  250.         if (got_frame) {  
  251.             tb = (AVRational) {  
  252.                 1, frame->sample_rate  
  253.             };  
  254.   
  255.             af = frame_queue_peek_writable(&is->sampq);  
  256.   
  257.             af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);  
  258.             af->pos = av_frame_get_pkt_pos(frame);  
  259.             af->serial = is->auddec.pkt_serial;  
  260.             af->duration = av_q2d((AVRational) {  
  261.                 frame->nb_samples, frame->sample_rate  
  262.             });  
  263.   
  264.             av_frame_move_ref(af->frame, frame);  
  265.             frame_queue_push(&is->sampq);  
  266.   
  267.         }  
  268.     } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);  
  269.   
  270. the_end:  
  271.     return ret;  
  272. }  
  273.   
  274. static int video_thread(void *arg)  
  275. {  
  276.     VideoState *is = arg;  
  277.     AVFrame *frame = av_frame_alloc();  
  278.     double pts;  
  279.     double duration;  
  280.     int ret;  
  281.     AVRational tb = is->video_st->time_base;  
  282.     AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);  
  283.   
  284.     for (;;) {  
  285.         ret = get_video_frame(is, frame);  
  286.   
  287.         if (ret < 0)  
  288.             goto the_end;  
  289.           
  290.         if (!ret)  
  291.             continue;  
  292.   
  293.         duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational) {  
  294.             frame_rate.den, frame_rate.num  
  295.         }) : 0);  
  296.   
  297.         pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);  
  298.   
  299.         queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);  
  300.     }  
  301.   
  302. the_end:  
  303.     return 0;  
  304. }  
  305.   
  306. /* return the wanted number of samples to get better sync if sync_type is video 
  307.  * or external master clock */  
  308. static int synchronize_audio(VideoState *is, int nb_samples)  
  309. {  
  310.     int wanted_nb_samples = nb_samples;  
  311.   
  312.     /* if not master, then we try to remove or add samples to correct the clock */  
  313.     if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {  
  314.         double diff, avg_diff;  
  315.         int min_nb_samples, max_nb_samples;  
  316.   
  317.         diff = get_clock(&is->audclk) - get_master_clock(is);  
  318.   
  319.         if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {  
  320.             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;  
  321.             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {  
  322.                 /* not enough measures to have a correct estimate */  
  323.                 is->audio_diff_avg_count++;  
  324.             } else {  
  325.                 /* estimate the A-V difference */  
  326.                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);  
  327.   
  328.                 if (fabs(avg_diff) >= is->audio_diff_threshold) {  
  329.                     wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);  
  330.                     min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));  
  331.                     max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));  
  332.                     wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);  
  333.                 }  
  334.                 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",  
  335.                 diff, avg_diff, wanted_nb_samples - nb_samples,  
  336.                 is->audio_clock, is->audio_diff_threshold);  
  337.             }  
  338.         } else {  
  339.             /* too big difference : may be initial PTS errors, so 
  340.                reset A-V filter */  
  341.             is->audio_diff_avg_count = 0;  
  342.             is->audio_diff_cum       = 0;  
  343.         }  
  344.     }  
  345.   
  346.     return wanted_nb_samples;  
  347. }  
  348. /** 
  349.  * Decode one audio frame and return its uncompressed size. 
  350.  * 
  351.  * The processed audio frame is decoded, converted if required, and 
  352.  * stored in is->audio_buf, with size in bytes given by the return 
  353.  * value. 
  354.  */  
  355. static int audio_decode_frame(VideoState *is)  
  356. {  
  357.     int data_size, resampled_data_size;  
  358.     int64_t dec_channel_layout;  
  359.     av_unused double audio_clock0;  
  360.     int wanted_nb_samples;  
  361.     Frame *af;  
  362.   
  363.     if (is->paused)  
  364.         return -1;  
  365.   
  366.     do {  
  367.         af = frame_queue_peek_readable(&is->sampq);  
  368.         frame_queue_next(&is->sampq);  
  369.     } while (af->serial != is->audioq.serial);  
  370.   
  371.     data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame), af->frame->nb_samples, af->frame->format, 1);  
  372.   
  373.     dec_channel_layout =  
  374.     (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?  
  375.     af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));  
  376.       
  377.     wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);  
  378.   
  379.     if (af->frame->format    != is->audio_src.fmt                   ||  
  380.             dec_channel_layout       != is->audio_src.channel_layout ||  
  381.             af->frame->sample_rate   != is->audio_src.freq           ||  
  382.             (wanted_nb_samples       != af->frame->nb_samples && !is->swr_ctx)) {  
  383.   
  384.         swr_free(&is->swr_ctx);  
  385.         is->swr_ctx = swr_alloc_set_opts(NULL, is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,  
  386.         dec_channel_layout,  af->frame->format, af->frame->sample_rate, 0, NULL);  
  387.   
  388.         swr_init(is->swr_ctx);  
  389.   
  390.         is->audio_src.channel_layout = dec_channel_layout;  
  391.         is->audio_src.channels       = av_frame_get_channels(af->frame);  
  392.         is->audio_src.freq = af->frame->sample_rate;  
  393.         is->audio_src.fmt = af->frame->format;  
  394.     }  
  395.   
  396.     if (is->swr_ctx) {  
  397.         const uint8_t **in = (const uint8_t **)af->frame->extended_data;  
  398.         uint8_t **out = &is->audio_buf1;  
  399.         int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;  
  400.         int out_size  = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);  
  401.         int len2;  
  402.   
  403.         if (wanted_nb_samples != af->frame->nb_samples) {  
  404.             if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,  
  405.             wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {  
  406.                 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");  
  407.                 return -1;  
  408.             }  
  409.         }  
  410.         av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);  
  411.   
  412.         len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);  
  413.   
  414.         is->audio_buf = is->audio_buf1;  
  415.         //每声道采样数 x 声道数 x 每个采样字节数    
  416.         resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);  
  417.     } else {  
  418.         is->audio_buf = af->frame->data[0];  
  419.         resampled_data_size = data_size;  
  420.     }  
  421.   
  422.     audio_clock0 = is->audio_clock;  
  423.     /* update the audio clock with the pts */  
  424.     //  1/af->frame->sample_rate=采样一个样本点所需要的时候  
  425.     if (!isnan(af->pts))  
  426.         is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;  
  427.     else  
  428.         is->audio_clock = NAN;  
  429.     is->audio_clock_serial = af->serial;  
  430.   
  431. #ifdef DEBUG  
  432.     {  
  433.         static double last_clock;  
  434.         printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",  
  435.         is->audio_clock - last_clock,  
  436.         is->audio_clock, audio_clock0);  
  437.         last_clock = is->audio_clock;  
  438.     }  
  439. #endif  
  440.     return resampled_data_size;  
  441. }  
  442.   
  443. /* prepare a new audio buffer */  
  444. static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)  
  445. {  
  446.     VideoState *is = opaque;  
  447.     int audio_size, len1;  
  448.   
  449.     audio_callback_time = av_gettime_relative();  
  450.   
  451.     while (len > 0) {  
  452.         if (is->audio_buf_index >= is->audio_buf_size) {  
  453.             audio_size = audio_decode_frame(is);  
  454.             if (audio_size < 0) {  
  455.                 /* if error, just output silence */  
  456.                 is->audio_buf      = is->silence_buf;  
  457.                 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;  
  458.             } else {  
  459.                 is->audio_buf_size = audio_size;  
  460.             }  
  461.             is->audio_buf_index = 0;  
  462.         }  
  463.         len1 = is->audio_buf_size - is->audio_buf_index;  
  464.         if (len1 > len)  
  465.             len1 = len;  
  466.         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);  
  467.         len -= len1;  
  468.         stream += len1;  
  469.         is->audio_buf_index += len1;  
  470.     }  
  471.     is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;  
  472.     /* Let's assume the audio driver that is used by SDL has two periods. */  
  473.     if (!isnan(is->audio_clock)) {  
  474.         /*set_clock_at第二个参数是计算音频已经播放的时间,相当于video中的上一帧的播放时间,如果不同过SDL,例如直接使用linux下的dsp设备进行播放,那么我们可以通过ioctl接口获取到驱动的audiobuffer中还有多少数据没播放,这样,我们通过音频的采样率和位深,可以很精确的算出音频播放到哪个点了,但是此处的计算方法有点让人看不懂*/  
  475.         set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);  
  476.         sync_clock_to_slave(&is->extclk, &is->audclk);  
  477.     }  
  478. }  
  479.   
  480. /* this thread gets the stream from the disk or the network */  
  481. static int read_thread(void *arg)  
  482. {  
  483.     VideoState *is = arg;  
  484.     AVFormatContext *ic = NULL;  
  485.     int err, i, ret;  
  486.     AVPacket pkt1, *pkt = &pkt1;  
  487.     int64_t stream_start_time;  
  488.     int pkt_in_play_range = 0;  
  489.     AVDictionaryEntry *t;  
  490.     AVDictionary **opts;  
  491.     int orig_nb_streams;  
  492.     SDL_mutex *wait_mutex = SDL_CreateMutex();  
  493.     int scan_all_pmts_set = 0;  
  494.     int64_t pkt_ts;  
  495.     int video_index = -1;  
  496.     int audio_index = -1;  
  497.       
  498.     is->last_video_stream = is->video_stream = -1;  
  499.     is->last_audio_stream = is->audio_stream = -1;  
  500.     is->eof = 0;  
  501.   
  502.     ic = avformat_alloc_context();  
  503.   
  504.     avformat_open_input(&ic, is->filename, is->iformat, &format_opts);  
  505.     is->ic = ic;  
  506.   
  507.     is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;  
  508.   
  509.     is->realtime = is_realtime(ic);  
  510.   
  511.     for(i=0; i<ic->nb_streams; i++) {  
  512.         if(ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO &&  
  513.             video_index < 0) {  
  514.             video_index=i;  
  515.         }  
  516.         if(ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&  
  517.             audio_index < 0) {  
  518.             audio_index=i;  
  519.         }  
  520.     }  
  521.   
  522.     stream_component_open(is, audio_index);  
  523.   
  524.     stream_component_open(is, video_index);  
  525.   
  526.     for (;;) {  
  527.   
  528.         if (is->abort_request)  
  529.             break;  
  530.   
  531.         if (is->paused != is->last_paused) {  
  532.             is->last_paused = is->paused;  
  533.             if (is->paused)  
  534.                 is->read_pause_return = av_read_pause(ic);  
  535.             else  
  536.                 av_read_play(ic);  
  537.         }  
  538.   
  539.         if (is->seek_req) {  
  540.             int64_t seek_target = is->seek_pos;  
  541.             int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;  
  542.             int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;  
  543. // FIXME the +-2 is due to rounding being not done in the correct direction in generation  
  544. //      of the seek_pos/seek_rel variables  
  545.   
  546.             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);  
  547.             if (ret < 0) {  
  548.                 av_log(NULL, AV_LOG_ERROR,  
  549.                 "%s: error while seeking\n", is->ic->filename);  
  550.             } else {  
  551.                 if (is->audio_stream >= 0) {  
  552.                     packet_queue_flush(&is->audioq);  
  553.                     packet_queue_put(&is->audioq, &flush_pkt);  
  554.                 }  
  555.                 if (is->video_stream >= 0) {  
  556.                     packet_queue_flush(&is->videoq);  
  557.                     packet_queue_put(&is->videoq, &flush_pkt);  
  558.                 }  
  559.                 if (is->seek_flags & AVSEEK_FLAG_BYTE) {  
  560.                     set_clock(&is->extclk, NAN, 0);  
  561.                 } else {  
  562.                     set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);  
  563.                 }  
  564.             }  
  565.             is->seek_req = 0;  
  566.             is->queue_attachments_req = 1;  
  567.             is->eof = 0;  
  568.             if (is->paused)  
  569.                 step_to_next_frame(is);  
  570.         }  
  571.         if (is->queue_attachments_req) {  
  572.             if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {  
  573.                 AVPacket copy;  
  574.                 if ((ret = av_copy_packet(&copy, &is->video_st->attached_pic)) < 0)  
  575.                     goto fail;  
  576.                 packet_queue_put(&is->videoq, &copy);  
  577.                 packet_queue_put_nullpacket(&is->videoq, is->video_stream);  
  578.             }  
  579.             is->queue_attachments_req = 0;  
  580.         }  
  581.   
  582.         if (!is->paused &&  
  583.         (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&  
  584.         (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {  
  585.             if (loop != 1 && (!loop || --loop)) {  
  586.                 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);  
  587.             } else if (autoexit) {  
  588.                 ret = AVERROR_EOF;  
  589.                 goto fail;  
  590.             }  
  591.         }  
  592.         ret = av_read_frame(ic, pkt);  
  593.         if (ret < 0) {  
  594.             if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {  
  595.                 if (is->video_stream >= 0)  
  596.                     packet_queue_put_nullpacket(&is->videoq, is->video_stream);  
  597.                 if (is->audio_stream >= 0)  
  598.                     packet_queue_put_nullpacket(&is->audioq, is->audio_stream);  
  599.                 is->eof = 1;  
  600.             }  
  601.             if (ic->pb && ic->pb->error)  
  602.                 break;  
  603.             SDL_LockMutex(wait_mutex);  
  604.             SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);  
  605.             SDL_UnlockMutex(wait_mutex);  
  606.             continue;  
  607.         } else {  
  608.             is->eof = 0;  
  609.         }  
  610.         /* check if packet is in play range specified by user, then queue, otherwise discard */  
  611.         stream_start_time = ic->streams[pkt->stream_index]->start_time;  
  612.         pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;  
  613.   
  614.         pkt_in_play_range = duration == AV_NOPTS_VALUE ||  
  615.         (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *  
  616.         av_q2d(ic->streams[pkt->stream_index]->time_base) -  
  617.         (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000 <= ((double)duration / 1000000);  
  618.   
  619.         if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {  
  620.             packet_queue_put(&is->audioq, pkt);  
  621.         } else if (pkt->stream_index == is->video_stream && pkt_in_play_range  
  622.         && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {  
  623.             packet_queue_put(&is->videoq, pkt);  
  624.         } else {  
  625.             av_free_packet(pkt);  
  626.         }  
  627.     }  
  628.   
  629. fail:  
  630.     return 0;  
  631. }  
  632.   
  633. /* seek in the stream */  
  634. static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)  
  635. {  
  636.     if (!is->seek_req) {  
  637.         is->seek_pos = pos;  
  638.         is->seek_rel = rel;  
  639.         is->seek_flags &= ~AVSEEK_FLAG_BYTE;  
  640.         if (seek_by_bytes)  
  641.             is->seek_flags |= AVSEEK_FLAG_BYTE;  
  642.         is->seek_req = 1;  
  643.         SDL_CondSignal(is->continue_read_thread);  
  644.     }  
  645. }  
  646.   
  647. /* pause or resume the video */  
  648. static void stream_toggle_pause(VideoState *is)  
  649. {  
  650.     if (is->paused) {  
  651.         // last_updated 记录了上一帧视频图像显示时的系统时钟, av_gettime() - last_updated得到的结果刚好是pause这段时间间隔,  
  652.         //通过这种方式保证了frame_timer永远记录的是ffplay启动后到当前时间点的时间间隔          
  653.         is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;  
  654.         if (is->read_pause_return != AVERROR(ENOSYS)) {  
  655.             is->vidclk.paused = 0;  
  656.         }  
  657.         set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);  
  658.     }  
  659.     set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);  
  660.     is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;  
  661. }  
  662.   
  663. static void toggle_pause(VideoState *is)  
  664. {  
  665.     stream_toggle_pause(is);  
  666.     is->step = 0;  
  667. }  




/*
44100是每秒采样次数
一般pcm如果是双通道16位的话(32bit),每个样本是4Byte
所以 一秒的数据量是4410*4bytes  实践中ACC是1024(4096字节)个样本一个avframe---MP3是1152
也就是一秒内有44100/1024个avframe被打上了PTS,一秒内约 43或44个avframe来包含44100*4/4096的数据


用32位表示其实是用32位空间来存储
就是4字节才能把2个声道的信息全部存下来进行编码
*/


/*
serial这个变量主要是维护数据的一致性


PacketQueue队列自己有一个serail变量
他管理的链表每个包有一个serail变量
当插入flush_pkt包的时候,队列的serail变量会++,说明又是一个新开始


FrameQueue队列的每一帧图像都有一个serail变量(解码之前的包serail的值),
显示之前,他先和PacketQueue队列的serail变量比较,,,,


Clock 结结中也有这个变量


目前主要是seek的时候,插入flush_pkt包 ,这个时候PacketQueue被分成两部分
flush_pkt之前的部分,和flush_pkt之后的部分,之前的serial=1,测试之后的为serial=2;


而FrameQueue队列只能依据serail变量来区分seek之前的包,和之后的包,之前的肯定就不会再显示了


Clock结构中的这个变量,也是这个作用
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值