mplayer先播视频后播音频的解决方法

static double update_video(int *blit_frame)
{
    sh_video_t * const sh_video = mpctx->sh_video;
    //--------------------  Decode a frame: -----------------------
    double frame_time;
    *blit_frame = 0; // Don't blit if we hit EOF
    if (!correct_pts) {
 unsigned char* start=NULL;
 void *decoded_frame = NULL;
 int drop_frame=0;
 int in_size;
 int full_frame;

    do {
 current_module = "video_read_frame";
 frame_time = sh_video->next_frame_time;
 in_size = video_read_frame(sh_video, &sh_video->next_frame_time,
       &start, force_fps);
#ifdef CONFIG_DVDNAV
 /// wait, still frame or EOF
 if (mpctx->stream->type == STREAMTYPE_DVDNAV && in_size < 0) {
     if (mp_dvdnav_is_eof(mpctx->stream))
                return -1;
     if (mpctx->d_video)
                mpctx->d_video->eof = 0;
     if (mpctx->d_audio)
                mpctx->d_audio->eof = 0;
     mpctx->stream->eof = 0;
 } else
#endif
 if (in_size < 0)
     return -1;
 if (in_size > max_framesize)
     max_framesize = in_size; // stats
 drop_frame = check_framedrop(frame_time);
 current_module = "decode_video";
#ifdef CONFIG_DVDNAV
 full_frame = 1;
 decoded_frame = mp_dvdnav_restore_smpi(&in_size,&start,decoded_frame);
 /// still frame has been reached, no need to decode
 if (in_size > 0 && !decoded_frame)
#endif
 decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
         sh_video->pts, &full_frame);

    if (full_frame) {

sh_video->timer += frame_time;

 // Time-based PTS recalculation.
 // The key to maintaining A-V sync is to not touch PTS until the proper frame is reached
 if (sh_video->pts != MP_NOPTS_VALUE) {
     if (sh_video->last_pts != MP_NOPTS_VALUE) {
  double pts = sh_video->last_pts + frame_time;
  double ptsdiff = fabs(pts - sh_video->pts);

  // Allow starting PTS recalculation at the appropriate frame only
  mpctx->framestep_found |= (ptsdiff <= frame_time * 1.5);

  // replace PTS only if we're not too close and not too far
  // and a correctly timed frame has been found, otherwise
  // keep pts to eliminate rounding errors or catch up with stream
  if (ptsdiff > frame_time * 20)
      mpctx->framestep_found = 0;
  if (ptsdiff * 10 > frame_time && mpctx->framestep_found)
      sh_video->pts = pts;
  else
      mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"Keeping PTS at %6.2f\n", sh_video->pts);
     }
     sh_video->last_pts = sh_video->pts;
 }
 if (mpctx->sh_audio)
     mpctx->delay -= frame_time;
 // video_read_frame can change fps (e.g. for ASF video)
 vo_fps = sh_video->fps;
 update_subtitles(sh_video, sh_video->pts, mpctx->d_sub, 0);
 update_teletext(sh_video, mpctx->demuxer, 0);
 update_osd_msg();
    }
#ifdef CONFIG_DVDNAV
 /// save back last still frame for future display
 mp_dvdnav_save_smpi(in_size,start,decoded_frame);
#endif

full_frame=1;/*赋值为1跳出do...while循环*/
    } while (!full_frame);

 current_module = "filter_video";
 *blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
          sh_video->pts));
    }
    else {
 int res = generate_video_frame(sh_video, mpctx->d_video);
 if (!res)
     return -1;

#if 0 //we need not get pts from vfilter
 ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
         VFCTRL_GET_PTS, &sh_video->pts);
#endif
 if (sh_video->pts == MP_NOPTS_VALUE) {
     mp_msg(MSGT_CPLAYER, MSGL_ERR, "pts after filters MISSING\n");
     sh_video->pts = sh_video->last_pts;
 }
 if (sh_video->last_pts == MP_NOPTS_VALUE)
     sh_video->last_pts= sh_video->pts;
 else if (sh_video->last_pts > sh_video->pts) {
     // make a guess whether this is some kind of discontinuity
     // we should jump along with or some wron timestamps we
     // should replace instead
            if (sh_video->pts < sh_video->last_pts - 20 * sh_video->frametime)
  sh_video->last_pts = sh_video->pts;
     else
         sh_video->pts = sh_video->last_pts + sh_video->frametime;
     mp_msg(MSGT_CPLAYER, MSGL_V, "pts value < previous\n");
 }
 frame_time = sh_video->pts - sh_video->last_pts;
 if (!frame_time)
     frame_time = sh_video->frametime;
 sh_video->last_pts = sh_video->pts;
 sh_video->timer += frame_time;
 if(mpctx->sh_audio)
     mpctx->delay -= frame_time;
 *blit_frame = res > 0;
    }

frame_time经过打印一直是0,所以要让它跳出do...while循环,需要手动将它赋值为1
 
    return frame_time;
}

posted @ 2011-12-06 10:43  general001  阅读(459)  评论(0编辑  收藏  举报