ijkplayer播放器剖析(五)视频同步与渲染机制分析

article/2025/8/24 16:01:01

ijkplayer播放器剖析系列文章:

kplayer播放器剖析(一)从应用层分析至Jni层的流程分析

ijkplayer播放器剖析(二)消息机制分析 

ijkplayer播放器剖析(三)音频解码与音频输出机制分析 

ijkplayer播放器剖析(四)音频解码与音频输出机制分析 

一、引言:

在前面的博客中,将音频解码播放及视频解码都分析了,这篇博客将单独针对视频同步及渲染来分析,看下ijkplayer是如何做的。本博客分析的同步方式为以音频为主,视频去同步音频。

二、同步前提的确认:

ijkplayer的同步前提跟其他的播放器略有不同,在ijkplayer中,会创建用于维护音频,视频的时钟及一个外部时钟,所有的同步操作都是基于这三个时钟来进行的。具体的变量如下:

Clock audclk

Clock vidclk

Clock extclk

那么,对于同步而言,我们需要确认的是,音频和视频的时钟是何时更新的,只要知道了各自的时钟,那么就只需要去分析同步策略了,先来看视频。

在视频渲染线程video_refresh中,对于即将渲染的下一帧,会在渲染前更新pts:

vp = frame_queue_peek(&is->pictq);

然后将数据的pts及当前系统时间设置到vidclk:

SDL_LockMutex(is->pictq.mutex);
if (!isnan(vp->pts))update_video_pts(is, vp->pts, vp->pos, vp->serial);
SDL_UnlockMutex(is->pictq.mutex);

看一下update_video_pts:

static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {/* update current video pts */set_clock(&is->vidclk, pts, serial);sync_clock_to_slave(&is->extclk, &is->vidclk);
}

我们前面知道,视频是去同步音频的,显然,音频pts的更新至关重要,看一下音频pts是如何更新的:audclk的时钟更新是在往audiotrack中写入数据的时候。
我们看一下ff_ffplay.c中用于往audiotrack中写数据的回调函数sdl_audio_callback

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

    if (!isnan(is->audio_clock)) {set_clock_at(&is->audclk, is->audio_clock - (double)(is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec - SDL_AoutGetLatencySeconds(ffp->aout), is->audio_clock_serial, ffp->audio_callback_time / 1000000.0);sync_clock_to_slave(&is->extclk, &is->audclk);}

音频pts更新的首要条件是判断is->audio_clock是否有效,那么这个is->audio_clock是怎么更新的呢?这个值是在往audiotrack中写数据时,获取待写入数据audio_decode_frame中去更新的:

audio_decode_frame@ff_ffplay.c:static int audio_decode_frame(FFPlayer *ffp)
{
.../* update the audio clock with the pts */if (!isnan(af->pts))is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;elseis->audio_clock = NAN;
....
}

当有效帧中含有效pts时,将进入if循环,audio_clock等于当前帧pts加上当前帧的采样总点数 / 采样率两者之和,当前帧的总点数 /采样率即当前帧的持续时间。得到了这个值之后,再看前面是如何更新音频时钟audclk的:

set_clock_at(&is->audclk, is->audio_clock - (double)(is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec - SDL_AoutGetLatencySeconds(ffp->aout), is->audio_clock_serial, ffp->audio_callback_time / 1000000.0);

注意第二个入参是一个实时pts,因为上面我们分析了audio_clock是在pts的基础上加上整个帧的持续时间的,故这里会用audio_clock减去已经写入到audiotrack中的buffer数据持续时间,并且还进行了latency校准,可以说,ijkplayer在音频时钟的更新上做的非常细节。将校准后的音频时钟更新之后,下面就是同步策略的分析了。

三、同步策略分析:

ijkplayer视频同步音频的策略在video_refresh@ff_ffplay.c中实现,我们先看下video_refresh是如何调入的:

static int video_refresh_thread(void *arg)
{FFPlayer *ffp = arg;VideoState *is = ffp->is;double remaining_time = 0.0;/* 如果不退出播放 */while (!is->abort_request) {/* 是否需要睡眠 */if (remaining_time > 0.0)av_usleep((int)(int64_t)(remaining_time * 1000000.0));remaining_time = REFRESH_RATE;if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))/* 调用同步及渲染函数 */video_refresh(ffp, &remaining_time);}return 0;
}

ijkplayer专门创建了一个video_refresh_thread用于处理视频渲染,看代码中,有一个变量remaining_time用于处理是否睡眠,实际上这个变量的值是由后面的同步策略来决定的,一帧视频需要渲染多长时间,均由这个值来判定,看一下同步处理及渲染的函数video_refresh:

static void video_refresh(FFPlayer *opaque, double *remaining_time)
{FFPlayer *ffp = opaque;VideoState *is = ffp->is;double time;Frame *sp, *sp2;/* 启用外部时钟 */if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)check_external_clock_speed(is);/* 特定模式 */if (!ffp->display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {...}if (is->video_st) {
retry: /* 缓存队列中无视频帧,则什么都不做 */if (frame_queue_nb_remaining(&is->pictq) == 0) {// nothing to do, no picture to display in the queue} else {double last_duration, duration, delay;Frame *vp, *lastvp;/* dequeue the picture *//* 将上一帧和即将显示的下一帧出列 */lastvp = frame_queue_peek_last(&is->pictq);vp = frame_queue_peek(&is->pictq);/* 视频缓冲队列若更新,将丢弃本帧 */if (vp->serial != is->videoq.serial) {frame_queue_next(&is->pictq);goto retry;}if (lastvp->serial != vp->serial)is->frame_timer = av_gettime_relative() / 1000000.0;if (is->paused)goto display;/* compute nominal last_duration *//* 1.计算理论上的两帧时间间隔:通过pts直接相减获得 */last_duration = vp_duration(is, lastvp, vp);/* 2.两帧时间间隔校准:获得校准后的的两帧播放间隔 */delay = compute_target_delay(ffp, last_duration, is);/* 更新当前系统时间 */time= av_gettime_relative()/1000000.0;if (isnan(is->frame_timer) || time < is->frame_timer)is->frame_timer = time;/* 当前系统时间如果小于计算出来的下一帧显示时间,将持续等待 */if (time < is->frame_timer + delay) {*remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);goto display;}/* 若已经到达该下一帧的显示时间,则更新显示时间 */is->frame_timer += delay;/* 如果当前系统时间大于下一帧渲染时间超过100ms,则直接更新播放时间为当前系统时间 */if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)is->frame_timer = time;SDL_LockMutex(is->pictq.mutex);if (!isnan(vp->pts))update_video_pts(is, vp->pts, vp->pos, vp->serial);SDL_UnlockMutex(is->pictq.mutex);/* 如果还有至少两帧待渲染:计算出下一帧的播放时间 */if (frame_queue_nb_remaining(&is->pictq) > 1) {Frame *nextvp = frame_queue_peek_next(&is->pictq);duration = vp_duration(is, vp, nextvp);/* 直接看if的最后面:如果当前系统时间大于预估的下一帧渲染时间的话,同时上层option设置了丢帧,则直接丢帧进入下一个retry */if(!is->step && (ffp->framedrop > 0 || (ffp->framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration) {frame_queue_next(&is->pictq);goto retry;}}/* 字幕处理 */if (is->subtitle_st) {while (frame_queue_nb_remaining(&is->subpq) > 0) {sp = frame_queue_peek(&is->subpq);if (frame_queue_nb_remaining(&is->subpq) > 1)sp2 = frame_queue_peek_next(&is->subpq);elsesp2 = NULL;if (sp->serial != is->subtitleq.serial|| (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))|| (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000)))){if (sp->uploaded) {ffp_notify_msg4(ffp, FFP_MSG_TIMED_TEXT, 0, 0, "", 1);}frame_queue_next(&is->subpq);} else {break;}}}/* release该帧并开启渲染 */frame_queue_next(&is->pictq);is->force_refresh = 1;SDL_LockMutex(ffp->is->play_mutex);if (is->step) {is->step = 0;if (!is->paused)stream_update_pause_l(ffp);}SDL_UnlockMutex(ffp->is->play_mutex);}
display:/* display picture */if (!ffp->display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)video_display2(ffp);}        
}

当视频队列中有待处理帧时,ijkplayer会将上一帧和当前待显示帧出列,通过这两帧附带的码流信息进行同步和校准,来看下具体是如何做同步的,首先通过vp_duration来得到一个直接的时间差值:

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {if (vp->serial == nextvp->serial) {/* 直接由两帧的pts相减获得 */double duration = nextvp->pts - vp->pts;if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)return vp->duration;elsereturn duration;} else {return 0.0;}
}

如果视频帧是连续的,则初步计算出来的两帧持续时间为pts的差值。这个差值还需要去校准,之后才能作为是判断播放还是丢帧的依据,可以说,同步校准是播放器最技术的内容。ijkplayer的同步校准是通过compute_target_delay函数来实现的,其原理主要是通过比对ijkplayer自己维护的视频和音频时钟的差值,来确定视频帧的播放时长(延长,缩短或者直接丢弃):

static double compute_target_delay(FFPlayer *ffp, double delay, VideoState *is)
{double sync_threshold, diff = 0;/* update delay to follow master synchronisation source *//* 以音频为主的同步模式 */if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {/* if video is slave, we try to correct big delays byduplicating or deleting a frame *//* 音视频时间差(单位:秒) = 当前视频时钟 - 当前音频时钟 */diff = get_clock(&is->vidclk) - get_master_clock(is);/* skip or repeat frame. We take into account thedelay to compute the threshold. I still don't knowif it is the best guess *//* 确定一个ijkplayer认为的同步区间:40ms~100ms */sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));/* -- by bbcallen: replace is->max_frame_duration with AV_NOSYNC_THRESHOLD *//* 音视频的时间差在100s内都去做同步操作 */if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {/* 1.视频落后音频40ms~100ms区间内:缩短这两帧的显示间隔 */if (diff <= -sync_threshold)delay = FFMAX(0, delay + diff);/* 2.视频超前音频至少40ms~100ms且视频前后两帧的时间间隔大于150ms:增加两帧间的播放间隔以等待音频 */else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)delay = delay + diff;/* 3.视频超前音频40ms~100ms且两帧间的间隔较小:延长一个delay */else if (diff >= sync_threshold)delay = 2 * delay;}}if (ffp) {ffp->stat.avdelay = delay;ffp->stat.avdiff  = diff;}
#ifdef FFP_SHOW_AUDIO_DELAYav_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",delay, -diff);
#endifreturn delay;
}

入参delay是前面计算出来的视频前后两帧的pts差值,diff则是当前音视频的时钟差,sync_threshold是一个同步阈值,ijkplayer将通过这个同步阈值来决定视频帧的持续时长,其值是通过delay来动态得到的,通过计算,可以看到,其同步阈值的范围为40~100ms,计算出来了同步阈值之后,就是去进行同步的判断操作了,这里我比较好奇的是,ijkplayer的同步操作在100s以内都会去做的,不确定是否是单位的问题,来看一下ijkplayer罗列出的三种情况:

/* 音视频的时间差在100s内都去做同步校准操作 */
if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {/* 1.视频落后音频40ms~100ms区间内:缩短这两帧的显示间隔 */if (diff <= -sync_threshold)delay = FFMAX(0, delay + diff);/* 2.视频超前音频至少40ms~100ms且视频前后两帧的时间间隔大于150ms:增加两帧间的播放间隔以等待音频 */else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)delay = delay + diff;/* 3.视频超前音频40ms~100ms且两帧间的间隔较小:延长一个delay */else if (diff >= sync_threshold)delay = 2 * delay;
}

因为diff值为视频时钟减去音频时钟,如果该值为负,则表明是视频落后音频,如果该值为正,则是视频超前音频,先看情形一,如果视频此时已经落后音频了,则需要加快显示下一帧,那么自然就需要缩短当前帧的显示时长,故直接在diff的基础上加上两帧间隔,如果其值依旧小于0的话,就取零。再看视频超前音频的情形,这里分为了两种,如果视频超前时间较长,则增加当前帧的显示时间,等待音频,如果较短的话,则直接将当前帧显示时长增加一倍即可。最终,将该值返回。

回到外面的video_refresh,在通过计算和校准拿到最终的显示时长后,接下来需要做的就是去送显,is->frame_timer是ijkplayer用于维护当前视频帧显示时间的变量,将这个变量加上前面校准后的delay即是下一帧的视频显示时间,如果此时的系统时间小于下一帧的显示时间的话,那么直接等待即可,但是如果大于了下一帧的系统时间的话,就需要考虑丢帧了:

/* 如果还有至少两帧待渲染:计算出下一帧的播放时间 */
if (frame_queue_nb_remaining(&is->pictq) > 1) {Frame *nextvp = frame_queue_peek_next(&is->pictq);duration = vp_duration(is, vp, nextvp);/* 直接看if的最后面:如果当前系统时间大于预估的下一帧播放时间的话,同时上层option设置了丢帧,则直接丢帧进入下一个retry */if(!is->step && (ffp->framedrop > 0 || (ffp->framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration) {frame_queue_next(&is->pictq);goto retry;}
}

ijkplayer所有关于同步的策略就分析完了,下面就是去看ijkplayer如何进行送显的了。

四、渲染函数分析:

ijkplayer的视频渲染是由video_display2函数来完成的:

/* display the current picture, if any */
static void video_display2(FFPlayer *ffp)
{VideoState *is = ffp->is;if (is->video_st)video_image_display2(ffp);
}
static void video_image_display2(FFPlayer *ffp)
{VideoState *is = ffp->is;Frame *vp;Frame *sp = NULL;vp = frame_queue_peek_last(&is->pictq);if (vp->bmp) {...SDL_VoutDisplayYUVOverlay(ffp->vout, vp->bmp);...}...
}

看一下SDL_VoutDisplayYUVOverlay

int SDL_VoutDisplayYUVOverlay(SDL_Vout *vout, SDL_VoutOverlay *overlay)
{if (vout && overlay && vout->display_overlay)return vout->display_overlay(vout, overlay);return -1;
}

这里又是通过函数指针去实现的,先确认下vout的创建,在ijkplayer的create阶段,会去创建surface,在SDL_VoutAndroid_CreateForANativeWindow (ijksdl_vout_android_nativewindow.c)中会去实例化vout:

确认下vout的几个函数指针指向:

vout->opaque_class    = &g_nativewindow_class;
vout->create_overlay  = func_create_overlay;
vout->free_l          = func_free_l;
vout->display_overlay = func_display_overlay;

渲染函数是由func_display_overlay来完成的:

static int func_display_overlay(SDL_Vout *vout, SDL_VoutOverlay *overlay)
{SDL_LockMutex(vout->mutex);int retval = func_display_overlay_l(vout, overlay);SDL_UnlockMutex(vout->mutex);return retval;
}
static int func_display_overlay_l(SDL_Vout *vout, SDL_VoutOverlay *overlay)
{...switch(overlay->format) {case SDL_FCC__AMC: {// only ANativeWindow supportIJK_EGL_terminate(opaque->egl);/* 反射到mediacodec去进行渲染 */return SDL_VoutOverlayAMediaCodec_releaseFrame_l(overlay, NULL, true);}...
}

往下追一下,SDL_VoutOverlayAMediaCodec_releaseFrame_l->SDL_VoutAndroid_releaseBufferProxyP_l->SDL_VoutAndroid_releaseBufferProxy_l

static int SDL_VoutAndroid_releaseBufferProxy_l(SDL_Vout *vout, SDL_AMediaCodecBufferProxy *proxy, bool render)
{...sdl_amedia_status_t amc_ret = SDL_AMediaCodec_releaseOutputBuffer(opaque->acodec, proxy->buffer_index, render); ...
}

这里就可以看到还是调用的mediacodec的releaseOutputBuffer接口来进行视频帧的渲染了。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

五、补充:

视频渲染的函数分析并不复杂,但是有一个地方需要注意,那就是SDL_FCC__AMC这个case是如何确认的?首先,在视频解码线程func_run_sync中,会去调用ffp_queue_picture函数:

int ffp_queue_picture(FFPlayer *ffp, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
{return queue_picture(ffp, src_frame, pts, duration, pos, serial);
}
static int queue_picture(FFPlayer *ffp, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
{...alloc_picture(ffp, src_frame->format);...
}
static void alloc_picture(FFPlayer *ffp, int frame_format)
{...SDL_VoutSetOverlayFormat(ffp->vout, ffp->overlay_format);vp->bmp = SDL_Vout_CreateOverlay(vp->width, vp->height,frame_format,ffp->vout);...
}

跟进到SDL_Vout_CreateOverlay

SDL_VoutOverlay *SDL_Vout_CreateOverlay(int width, int height, int frame_format, SDL_Vout *vout)
{if (vout && vout->create_overlay)return vout->create_overlay(width, height, frame_format, vout);return NULL;
}

在前面我们已经分析了vout的函数指针,看一下其函数实现:

static SDL_VoutOverlay *func_create_overlay(int width, int height, int frame_format, SDL_Vout *vout)
{SDL_LockMutex(vout->mutex);SDL_VoutOverlay *overlay = func_create_overlay_l(width, height, frame_format, vout);SDL_UnlockMutex(vout->mutex);return overlay;
}
static SDL_VoutOverlay *func_create_overlay_l(int width, int height, int frame_format, SDL_Vout *vout)
{switch (frame_format) {case IJK_AV_PIX_FMT__ANDROID_MEDIACODEC:return SDL_VoutAMediaCodec_CreateOverlay(width, height, vout);default:return SDL_VoutFFmpeg_CreateOverlay(width, height, frame_format, vout);}
}

这里又需要确认frame_format,这个值是在填充buffer的时候写入的:

amc_fill_frame@ijkmedia\ijkplayer\android\pipeline\ffpipenode_android_mediacodec_vdec.c:
static int amc_fill_frame(IJKFF_Pipenode            *node,AVFrame                   *frame,int                       *got_frame,int                        output_buffer_index,int                        acodec_serial,SDL_AMediaCodecBufferInfo *buffer_info)
{...frame->format = IJK_AV_PIX_FMT__ANDROID_MEDIACODEC;...
}

确认了format,进入到mediacodec的case:

SDL_VoutOverlay *SDL_VoutAMediaCodec_CreateOverlay(int width, int height, SDL_Vout *vout)
{...overlay->format       = SDL_FCC__AMC;...
}

这里就是最终确认使用mediacodec来进行送显的依据。

六、总结:

ijkplayer的同步原理就是比对视频和音频的时钟差值,来确音频和视频谁超前,然后通过视频前后两帧的pts差值来决定执行哪种策略,最后就是将校准后的这个值同当前系统时间对比来确认最终的送显时间:

 如果你对音视频开发感兴趣,觉得文章对您有帮助,别忘了点赞、收藏哦!或者对本文的一些阐述有自己的看法,有任何问题,欢迎在下方评论区讨论!

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓


http://chatgpt.dhexx.cn/article/bpTNpmIC.shtml

相关文章

ijkplayer播放器详解使用教程

1.认识ijkplayer 最近公司准备开发一款视频播放及直播的应用&#xff0c;找了许多开源的框架&#xff0c;大部分都是基于ffmpeg开发的。最开始准备用Vitamio框架开发的&#xff0c;相关的文章也比较丰富&#xff0c;结果对于非个人移动应用均需购买Vitamio使用授权。不过B站开…

ijkplayer播放器架构从原型到升级

ijkplayer是一款跨平台的播放器&#xff0c;支持Android与iOS端&#xff0c;核心部分基于ffmpeg&#xff0c;支持Android的mediacodec硬解与iOS的videotoolbox硬解&#xff0c;视频图像采用OpenGL进行渲染。许多主流播放器都使用ijkplayer作为播放方案。接下来我们从核心播放流…

游戏手柄改typec接口

前言 几年前买的杂牌游戏手柄坏了好久&#xff0c;连接十分不稳定&#xff0c;稍微动一下线就会断连&#xff0c;我推断是线的质量不好&#xff0c;理论上将把线换掉应该就好了。一不做二不休&#xff0c;我想直接改成typec接口&#xff0c;手柄与数据线分离&#xff0c;这样就…

nl80211_iftype接口类型详解

NL80211_IFTYPE_UNSPECIFIED 上层协议未指定硬件接口类型&#xff0c;由驱动指定 NL80211_IFTYPE_ADHOC independent BSS member&#xff0c;各个无线主机之间对等交换数据 NL80211_IFTYPE_STATION managed BSS member NL80211_IFTYPE_AP 接入点&#xff0c;通常一端通过有…

android接口和type c对比,USB Type-C究竟比3.5mm音频接口好在哪里?

随着苹果宣布将在iPhone7/7 Plus上取消传统的3.5mm音频接口,不少动作快的手机厂商已经即使跟进了,目前乐视所有新机和摩托罗拉Moto Z均使用USB Type-C接口代替3.5mm音频接口,这样做究竟有什么好处呢? 基础知识 首先我们需要知道,3.5mm接口所传输的是立体声模拟音频,这也就…

TYPE-C接口的定义诠释以及功能参数挖掘

现在的安卓手机大多都采用了Type-C接口&#xff0c;如华为、荣耀、小米、三星、魅族等。对于这个接口&#xff0c;大家不再陌生&#xff0c;但大多数人对它的认识还停留在 “支持正反插”、“用来充电” 的基础层面。今天就来深入挖掘一下TYPE-C发展七年至今&#xff0c;为何能…

Type-C接口原理图,附引脚说明

维基链接&#xff1a;https://zh.wikipedia.org/wiki/USB_Type-C 针名描述针名描述A1GND接地B12GND接地A2SSTXp1SuperSpeed差分信号#1&#xff0c;TX&#xff0c;正B11SSRXp1SuperSpeed差分信号#1&#xff0c;RX&#xff0c;正A3SSTXn1SuperSpeed差分信号#1&#xff0c;TX&…

typec接口知识

typec接口定义(24脚) typec母头 typec公头(一对D,D-,只有一个CC脚&#xff0c;另一个CC脚变成了VCONN) D/D-&#xff1a;当USB3接口不可用的时候&#xff0c;这些引脚为USB2信号提供信号通道。 Vbus/GND&#xff1a;这些引脚能够为上行数据接口提供100W的供电能力&#xff0c;…

深入学习USB(6)USB Type-C接口定义概念解析

文章目录 **一、Usb type c接口定义介绍****二、USB3.1 type-c接口特性****三、USB Type-C接口的优点****四、usb type-c接引脚定义****五、usb type-c接口主要功能****六、usb type-c接口工作流程**七、市场上Type-C/PD有哪几种分类呢&#xff1f; 一、Usb type c接口定义介绍…

lightning接口_苹果Lightning接口与Type-C接口,谁更胜一筹?

曾几何时,在苹果的强势助攻下,Lightning接口在数码界曾一度混得风生水起!然而,近年来随着智能手机的发展,手机接口快速升级,其中Type-C接口凭借更快的数据传输、充电速度等优势,越来越多的出现在大家的视线中,隐隐盖过Lightning接口的风头,就连特立独行的苹果也对其青…

Type-C接口技术(一)

前言 电子产品接口的迅速发展是电子技术迅速发展的一个缩影&#xff0c;随着现在电子产品对数据传输和充电功率要求越来越高的情况下&#xff0c;一些以前常用接口开始慢慢被淘汰&#xff0c;而支持更高速率和充电功率的的Type-C接口慢慢开始大放异彩&#xff0c;此外支持盲插…

浅谈一下Type-C接口发展历程

1996年&#xff0c;由英特尔、微软、ibm等多家公司联合设计的usb标准问世&#xff0c;键盘、鼠标、智能手机以及打印机等等大多使用usb标准来实现供电和数据传输。 usb接口从诞生之初就是为了实现通用这个目的。在usb诞生之前&#xff0c;键盘、鼠标多使用ps二接口&#xff0c;…

TYPE-C接口电路设计篇(一)

常见USB接口类型 随着USB Type-C接口的推行&#xff0c;USB Type-C是一种通用串行总线&#xff08;USB&#xff09;的硬件接口形式&#xff0c;USB Type-C接口在消费类产品普及程度越来越高&#xff0c;常见的适配器、笔电、手机等产品都兼容USB Type-C设计&#xff0c;接口多…

Type-C接口

TYPE-C接口 USB Type-C接口的命名原语USB Type-C连接器&#xff0c;这是一种坚固的易于使用的接口。支持正反插&#xff0c;方便快捷。支持超高速率通信功能和功率输出。最大传输速率10Gbits/S&#xff0c;最大输出功率100W&#xff0c;最大电流5A。大小8.3mm X 2.5mm。 具有…

一文带你搞清楚USB、type-C、雷电三接口之间的区别与联系

缘起 最近某些新电脑的发布,看到带了全功能的type-c接口,一直搞不懂什么type-c还有什么全功能,半功能?和雷电3又有什么区别,雷电3又有什么全速,半速。由于搞不清,所以网上看了很多资料,这里总结一下以备后续查阅 说说USB 你肯定会说,这个我知道,就是下面这种的 没…

USB Type C 接口引脚详解

1. Type C 接口特点 Type C 是一组对称的连接器&#xff0c;在使用的过程中不需要如同使用 USBA&#xff0c;MinUSB&#xff0c;MicroUSB 那样来辨别接口方向。其次能够承受较高的功率所以可以支持高达 100W 的功率&#xff0c;所以使用该接口可以更好的支持快速充电&#xff0…

Macbook技巧,Type-c接口失灵怎么办

有时Macbook Pro电脑突然出现Type-c接口失灵的情况&#xff0c;这该怎么解决呢&#xff1f;可以参考小编的操作方法 1.关机 2.按下键盘右侧的 Shift键&#xff0c;左侧的Control和Option键不放。此时电脑会开机&#xff0c;等进入显示白条的状态&#xff0c;不要松开手&#x…

Java Type接口 运行时获取泛型类型

一、Type接口 Type是所有类型的父接口&#xff0c;他有4个子接口和一个实现类。 Class比较常见&#xff0c;它表示的是原始类型。Class类的对象表示JVM中的一个类或接口。每个Java类在JVM里都表现为一个Class对象&#xff0c;可以通过“类名.class”、“对象.getClass()”、…

关于type_C接口

文章目录 概要&#xff1a;一、引脚定义二、六脚Type_c三、12脚Type_c四、16脚Type_c五、usb3.0 概要&#xff1a; type-C接口外观好看&#xff0c;双面插等众多优点&#xff0c;已经成为了现在主流的接口。 一、引脚定义 VBus:总线电源&#xff0c;USB PD协议可配置电压&…

TYPE-C接口引脚详解

Type-C口有4对TX/RX分线&#xff0c;2对USBD/D-&#xff0c;一对SBU&#xff0c;2个CC&#xff0c;另外还有4个VBUS和4个地线。 1、当Type-C接口仅用作传输DP信号时&#xff0c;则可利用4对TX/RX&#xff0c;从而实现4Lane传输&#xff0c;这种模式称为DPonly模式&#xff1b;…