目录

这次的代码主要解决了如下问题

存在的问题

 与之前版本的差异点

关于time_base的知识

video显示线程内等待audio的代码

audio线程计算 audio_clock的代码

完整的代码

 

在上一篇文章中FFMPEG学习(三)ffmpeg+SDL2.0制作简单的视频播放器(图像+声音),我们的代码里播放了MP4文件的音频跟视屏,但是会有音频晚于视屏的问题。这里我们进进行修改,使得视屏的播放基于音频播放时间进行同步

这次的代码主要解决了如下问题

 

1、播放完成无法自动结束的问题

2、音频与视屏播放无法同步时间问题

 

存在的问题

1、概率性执行完成之后发生段错,gdb调试暂时没有结论。后续再优化

2、只考虑了音频比视频慢的情况处理,如果银屏比视频更快这个情况,是不是也要在audio线程内等待?

3、代码内视屏播放时间使用的是pts时间,而非dts。这样是否可以考虑到B帧 的dts、pts不相等的问题?

 

代码逻辑大致如下(暂时未考虑存在B帧的情况,认为视屏的dts与pts相同的前提下)

 与之前版本的差异点

1、主线程是等待video播放线程结束再退出的,解决了播放完成无法退出,必须kill -9强杀的问题

2、一共三条线程

2.1、主线程读取视屏流,放到对应的队列中

2.2、一条音频播放线程,更新播放器的时钟

2.3、一条视屏播放线程,判断播放器时钟与当前帧的pts比较,显示图像

 

关于time_base的知识

暂时可以理解为ffmpeg内的一种时间单位,等同于提倡生活中的其他单位一样:米、千米每小时、千克等等

AVRational time_base;typedef struct AVRational{int num; ///< Numeratorint den; ///< Denominator
} AVRational;

从AVRational 的定义中我们可以看到这个时间使用分数来表示的,只有使用相同的时间基,计算出来的时间才有对比的意义。

不管是从设备采集信息保存到文件,还是一个文件播放出图像。都会有这样几个过程

1、mux/demux(分装/解封装)

2、codec/decode(bian/解码)

3、Raw data (YUV/PCM源数据)

每个过程向另一个过程转换,都需要转换这个time_base。

 

video显示线程内等待audio的代码

video_pts *= av_q2d(is->video_st->time_base);
video_pts = synchronize_video(is, pFrame, video_pts);while(1)
{//audio_clock时间再audio线程里播放,更新这个时间audio_pts = is->audio_clock;if (video_pts <= audio_pts) break;int delayTime = (video_pts - audio_pts) * 1000;delayTime = delayTime > 5 ? 5:delayTime;SDL_Delay(delayTime);
}

audio线程计算 audio_clock的代码

//基本思路是根据当前音频的声道数,采样位数,采样率,还有本次copy的数据大小,来计算播放玩buffer内数据的时间(这个时间不是很准确)
n = is->audioFrame->channels * is->audio_st->codec->channels;
is->audio_clock += (double) len1 / (double) (n * is->audio_st->codec->sample_rate);//time = bufsize /(声道数 * 采样位数 * 采样率)
//(声道数 * 采样位数 * 采样率)这一块可以理解为一秒钟可以播放的数据的大小

完整的代码

/* *************************************************************************       Filename:  sync_play.c*    Description:  *        Version:  1.0*        Created:  2020年07月08日 22时12分10秒*       Revision:  none*       Compiler:  gcc*         Author:  YOUR NAME (), *        Company:  * ************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>#include <libavutil/pixfmt.h>#include <libswscale/swscale.h>#include <SDL.h>#include <SDL_audio.h>#include <SDL_types.h>#include <SDL_name.h>#include <SDL_main.h>#include <SDL_config.h>#include <SDL2/SDL_thread.h>
#ifdef __cplusplus
};
#endif
#include <stdio.h>//Refresh
#define SFM_REFRESH_EVENT  (SDL_USEREVENT + 1)
//audio play end
#define SFM_AUDIOEND_EVENT  (SDL_USEREVENT + 1)//先按照提供的acc文件播放,后续修改
#define SDL_AUDIO_BUFFER_SIZE 1024
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
#define PLAY_REFRESH_TIME			10		//刷新时间间隔#define MAX_AUDIO_SIZE (25 * 16 * 1024)
#define MAX_VIDEO_SIZE (25 * 256 * 1024)typedef struct PacketQueue {AVPacketList *first_pkt, *last_pkt;		//首尾指针int nb_packets;				//包个数int size;					//队列大小SDL_mutex *mutex;				//队列互斥锁SDL_cond *cond;				//队列全局变量
} PacketQueue;typedef struct VideoState {AVFormatContext *VideoFormatCtx;AVCodecContext *aCodecCtx; //音频解码器AVCodecContext *vCodecCtx; //音频解码器AVFrame *audioFrame;// 解码音频过程中的使用缓存PacketQueue audioq; //音频队列	unsigned int audio_buf_size;unsigned int audio_buf_index;//AVPacket audio_pkt;uint8_t *audio_pkt_data;uint8_t *audio_pkt_size;uint8_t *audio_buf;// 做两个线程同步使用double audio_clock; ///音频时钟double video_clock; ///<pts of last decoded frame / predicted pts of next decoded frameAVStream *video_st; //视频流AVStream *audio_st; //音频流PacketQueue videoq;	//视频队列SDL_Thread *video_tid;  //视频线程idSDL_Thread *refresh_tid;  //视频刷新线程idSDL_AudioDeviceID audioID;	//audio模块打开的设备ID} VideoState;
//SDL播放回调
void audio_callback(void *userdata, Uint8 *stream, int len);
//播放流队列初始化
void packet_queue_init(PacketQueue *q);
//播放流添加入队列
int packet_queue_put(PacketQueue *q, AVPacket *pkt);
//播放流出队列
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block);
//从流中解码音频数据
int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size);
///显示视频帧
void Video_Display_To_Window(VideoState 		*is,			//video play 状态机   AVPacket 		*packet,		//包AVFrame 		*pFrame, 		//流AVFrame 		*pFrameYUV, 	//YUV流AVCodecContext 	*pCodecCtx,		//解码上下文SDL_Texture    	*bmp,			//显示句柄SDL_Renderer   	*renderer,		//渲染器句柄struct SwsContext *img_convert_ctx,//转码数据SDL_Rect 		rect			//显示区域);int sfp_refresh_thread(void *opaque);	//SDL新线程入口			//调整同步时间
static double synchronize_video(VideoState *is, AVFrame *src_frame, double pts);//音频处理
int audio_stream_component_open(VideoState *is, int stream_index);//视频播放线程
int video_play(void *arg);int thread_exit=0;// 分配解码过程中的使用缓存
//AVFrame* audioFrame = avcodec_alloc_frame();
AVFrame *audioFrame = NULL;
PacketQueue *audioq = NULL;
VideoState  is = {0};#undef main
int main(int argc, char *argv[])
{AVFormatContext	*pFormatCtx;				//视频上下文AVCodecContext	*pCodecCtx, *videoCodeCtx;				//解码上下文int				i, audioindex, videoindex;AVCodec			*pCodec, *videoCodec;		//解码器AVPacket 		*packet, *VideoPacket;			//打包的流数据AVFrame 		*FrameAudio, *FrameVideo, *FrameYUV;uint8_t* out_buffer;int numBytes;int wait_flag = 0;SDL_Event event; char *filename = "./test3.mp4";	//SDL threadif(1 == argc){printf("%s:%d parameter error \n", __func__, __LINE__);return -1;}audioFrame = av_frame_alloc();//==================固定的结构================start====================//1、注册所有的解码器av_register_all();//printf("%s -- %d\n", __func__, __LINE__);//2、分配空间pFormatCtx = avformat_alloc_context();//videoCodeCtx = avformat_alloc_context();//printf("%s -- %d\n", __func__, __LINE__);if(pFormatCtx){//3、打开文件if(avformat_open_input(&pFormatCtx, /*filename*/argv[1], NULL, NULL) != 0) //error{printf("Couldn't open input stream.\n");return -1;}}//dump 视频信息av_dump_format(pFormatCtx, 0, /*filename*/argv[1], 0);//4、检索视频流信息if(avformat_find_stream_info(pFormatCtx,NULL)<0){printf("Couldn't find stream information.\n");return -1;}//5、查找流位置audioindex = -1;videoindex = -1;for(i = 0; i < pFormatCtx->nb_streams; i ++){printf("cur type :%d\n", pFormatCtx->streams[i]->codec->codec_type);if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){audioindex = i;}if((pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) && (videoindex < 0)){videoindex = i;}}if((videoindex < 0) && (audioindex < 0)){printf("not fine audio or video stream! \n");return -1;}	printf("audioindex:%d, videoindex:%d\n", audioindex, videoindex);//6、解码上下文pCodecCtx = pFormatCtx->streams[audioindex]->codec;videoCodeCtx = pFormatCtx->streams[videoindex]->codec;//7、、获取视频解码器pCodec=avcodec_find_decoder(pCodecCtx->codec_id);videoCodec = avcodec_find_decoder(videoCodeCtx->codec_id);if(pCodec==NULL){printf("Codec not found.\n");return -1;}//8、、打开解码器if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){printf("Could not open audio codec.\n");return -1;}if(avcodec_open2(videoCodeCtx, videoCodec,NULL)<0){printf("Could not open video codec.\n");return -1;}
//======================固定的结构===========end====================//=================SDL=============start===========if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  printf( "Could not initialize SDL - %s\n", SDL_GetError()); return -1;}//video statu initis.VideoFormatCtx = avformat_alloc_context();is.VideoFormatCtx = pFormatCtx;is.audioFrame 	= av_frame_alloc();is.aCodecCtx 		= pCodecCtx;is.vCodecCtx 		= videoCodeCtx;is.audio_buf = (uint8_t *)malloc((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2);is.video_tid = SDL_CreateThread(video_play, "video_play", &is);is.audio_st = pFormatCtx->streams[audioindex];is.video_st = pFormatCtx->streams[videoindex];//printf("%s -- %d\n", __func__, __LINE__);///  打开SDL播放设备 - 结束
//=================SDL=============end=============//创建一个队列,并且初始化audio_stream_component_open(&is, audioindex);packet = av_packet_alloc();if(!packet){printf("Could not malloc packet.\n");return -1;}// Debug -- Beginprintf("比特率 %3d\n", pFormatCtx->bit_rate);printf("解码器名称 %s\n", pCodecCtx->codec->long_name);printf("time_base  %d \n", pCodecCtx->time_base);printf("声道数  %d \n", pCodecCtx->channels);printf("sample per second  %d \n", pCodecCtx->sample_rate);// Debug -- End//主线程。读取流到对应的队列。while(1){if((is.audioq.size > MAX_AUDIO_SIZE) || (is.videoq.size > MAX_VIDEO_SIZE)) {SDL_Delay(10);  //队列限制以下大小,防止一下读取太多的包,导致内存吃完continue;}if(av_read_frame(pFormatCtx, packet) < 0) //流已经读取完了{//Exit Threadthread_exit=1;break;}if(packet->stream_index == audioindex){packet_queue_put(&is.audioq, packet);//这里我们将数据存入队列 因此不调用 av_free_packet 释放}else if(packet->stream_index == videoindex) //display video stream{packet_queue_put(&is.videoq, packet);}else{// Free the packet that was allocated by av_read_frameav_free_packet(packet);}}printf("read finished!\n");wait_flag = 1;do{SDL_WaitEvent(&event);if(SFM_AUDIOEND_EVENT == event.type){printf("main thread wait audio thread exit!\n");wait_flag = 0;}}while(wait_flag);//等待ideo play线程退出SDL_WaitThread(is.video_tid, NULL);av_free(FrameAudio);avcodec_close(pCodecCtx);// Close the codecavformat_close_input(&pFormatCtx);// Close the video filereturn 0;
}void audio_callback(void *userdata, Uint8 *stream, int len)
{VideoState *is = (VideoState *)userdata;int len1, audio_data_size;int n = 0; if((NULL != is) && (NULL != stream))  //参数检查{int audio_buf_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;/*   len是由SDL传入的SDL缓冲区的大小,如果这个缓冲未满,我们就一直往里填充数据 */while (len > 0) {/*  audio_buf_index 和 audio_buf_size 标示我们自己用来放置解码出来的数据的缓冲区,*//*   这些数据待copy到SDL缓冲区, 当audio_buf_index >= audio_buf_size的时候意味着我*//*   们的缓冲为空,没有数据可供copy,这时候需要调用audio_decode_frame来解码出更/*   多的桢数据 */if (is->audio_buf_index >= is->audio_buf_size) {audio_data_size = audio_decode_frame(is, is->audio_buf, audio_buf_size/*sizeof(audio_buf)*/);/* audio_data_size < 0 标示没能解码出数据,我们默认播放静音 */if (audio_data_size < 0) {/* silence */is->audio_buf_size = 1024;/* 清零,静音 */memset(is->audio_buf, 0, is->audio_buf_size);} else {is->audio_buf_size = audio_data_size;}is->audio_buf_index = 0;}/*  查看stream可用空间,决定一次copy多少数据,剩下的下次继续copy */len1 = is->audio_buf_size - is->audio_buf_index;if (len1 > len) {len1 = len;}//音频PTS暂时现这样写,坑了再改if(is->audio_st->codec){//n = 2 * is->audio_st->codec->channels;n = is->audioFrame->channels * is->audio_st->codec->channels;is->audio_clock += (double) len1 / (double) (n * is->audio_st->codec->sample_rate);}memcpy(stream, (uint8_t *) is->audio_buf + is->audio_buf_index, len1);len -= len1;stream += len1;is->audio_buf_index += len1;}}
}//初始化队列
void packet_queue_init(PacketQueue *q) 
{memset(q, 0, sizeof(PacketQueue));q->mutex = SDL_CreateMutex();q->cond = SDL_CreateCond();
}//数据进入到队列中
int packet_queue_put(PacketQueue *q, AVPacket *pkt)
{AVPacketList *pkt1;if (av_dup_packet(pkt) < 0) {return -1;}pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));if (!pkt1)return -1;pkt1->pkt = *pkt;pkt1->next = NULL;SDL_LockMutex(q->mutex);if (!q->last_pkt)q->first_pkt = pkt1;elseq->last_pkt->next = pkt1;q->last_pkt = pkt1;q->nb_packets++;q->size += pkt1->pkt.size;SDL_CondSignal(q->cond);SDL_UnlockMutex(q->mutex);return 0;
}//从队列中取走数据
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) 
{AVPacketList *pkt1;int ret;SDL_LockMutex(q->mutex);for (;;) {pkt1 = q->first_pkt;if (pkt1) {q->first_pkt = pkt1->next;if (!q->first_pkt)q->last_pkt = NULL;q->nb_packets--;q->size -= pkt1->pkt.size;*pkt = pkt1->pkt;av_free(pkt1);ret = 1;break;} else if (!block) {ret = 0;break;} else {SDL_CondWait(q->cond, q->mutex);}}SDL_UnlockMutex(q->mutex);return ret;
}//解码流数据到
int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size)
{static AVPacket *pkt;static uint8_t *audio_pkt_data = NULL;static int audio_pkt_size = 0;int len1, data_size;SDL_Event event;pkt = av_packet_alloc();for(;;){if(packet_queue_get(&is->audioq, pkt, 0/*1*/) < 0){return -1;}//printf("%s %d\n", __func__, __LINE__);is->audio_pkt_data = pkt->data;is->audio_pkt_size = pkt->size;if(is->audio_pkt_size <= 0){//向主线程发送音频播放完成的消息event.type = SFM_AUDIOEND_EVENT;SDL_PushEvent(&event);return 0;   //没有数据,直接返回}while(is->audio_pkt_size > 0){int got_picture;int ret = avcodec_decode_audio4( is->aCodecCtx, is->audioFrame, &got_picture, pkt);if( ret < 0 ) {printf("Error in decoding audio frame.\n");exit(0);}//printf("%s %d\n", __func__, __LINE__);if( got_picture ) {int in_samples = is->audioFrame->nb_samples;short *sample_buffer = (short*)malloc(is->audioFrame->nb_samples * 2 * 2);memset(sample_buffer, 0, is->audioFrame->nb_samples * 4);int i=0;float *inputChannel0 = (float*)(is->audioFrame->extended_data[0]);//printf("%s %d in_samples:%d \n", __func__, __LINE__, in_samples);// Mono  单声道if( is->audioFrame->channels == 1 ) {for( i=0; i<in_samples; i++ ) {float sample = *inputChannel0++;if( sample < -1.0f ) {sample = -1.0f;} else if( sample > 1.0f ) {sample = 1.0f;}sample_buffer[i] = (int16_t)(sample * 32767.0f);}} else { // Stereo  双声道float* inputChannel1 = (float*)(is->audioFrame->extended_data[1]);for( i=0; i<in_samples; i++) {sample_buffer[i*2] = (int16_t)((*inputChannel0++) * 32767.0f);sample_buffer[i*2+1] = (int16_t)((*inputChannel1++) * 32767.0f);}}memcpy(audio_buf,sample_buffer,in_samples*4);free(sample_buffer);}		is->audio_pkt_size -= ret;if (is->audioFrame->nb_samples <= 0){continue;}data_size = is->audioFrame->nb_samples * 4;return data_size;}if(pkt->data)av_free_packet(pkt);}
}///显示视频帧
void Video_Display_To_Window(VideoState 		*is,			//video play 状态机AVPacket 		*packet,		//包AVFrame 		*pFrame, 		//流AVFrame 		*pFrameYUV, 	//YUV流AVCodecContext 	*pCodecCtx,		//解码上下文SDL_Texture    	*bmp,			//显示句柄SDL_Renderer   	*renderer,		//渲染器句柄struct SwsContext *img_convert_ctx,//转码数据SDL_Rect 		rect			//显示区域)
{int got_picture;SDL_Rect DisplayRect = {0};int ret = 0;double video_pts = 0; //当前视频的ptsdouble audio_pts = 0; //音频ptsDisplayRect.x = rect.x;DisplayRect.y = rect.y;DisplayRect.w = rect.w;DisplayRect.h = rect.h;ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);if(ret < 0){printf("Decode Error.\n");return -1;}if (packet->dts == AV_NOPTS_VALUE && pFrame->opaque&& *(uint64_t*) pFrame->opaque != AV_NOPTS_VALUE){video_pts = *(uint64_t *) pFrame->opaque;}else if (packet->dts != AV_NOPTS_VALUE){video_pts = packet->dts;}else{video_pts = 0;}
#if 0printf("%s %d !\n", __func__, __LINE__);printf("num:%d den:%d\n", is->video_st->time_base.num, is->video_st->time_base.den);printf("num:%d den:%d\n", is->aCodecCtx->time_base.num, is->aCodecCtx->time_base.den);video_pts *= av_q2d(is->video_st->time_base);printf("video_pts:%f !\n", video_pts);video_pts = synchronize_video(is, pFrame, video_pts);printf("%s %d !\n", __func__, __LINE__);printf("video_pts: %f, audio_pts:%f\n", video_pts, is->audio_clock);
#elsevideo_pts *= av_q2d(is->video_st->time_base);video_pts = synchronize_video(is, pFrame, video_pts);
#endifwhile(1){//audio_clock时间再audio线程里播放,更新这个时间audio_pts = is->audio_clock;if (video_pts <= audio_pts) break;int delayTime = (video_pts - audio_pts) * 1000;delayTime = delayTime > 5 ? 5:delayTime;SDL_Delay(delayTime);}if(got_picture){	 //printf("update texture to SDL widows!\n");sws_scale(img_convert_ctx,(uint8_t const * const *)pFrame->data,pFrame->linesize,0,pCodecCtx->height,pFrameYUV->data,pFrameYUV->linesize);////iPitch 计算yuv一行数据占的字节数SDL_UpdateTexture( bmp, &DisplayRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );//SDL_UpdateYUVTexture(bmp, &rect, pFrameYUV->data[0], pFrameYUV->linesize[0], pFrameYUV->data[1], pFrameYUV->linesize[1], pFrameYUV->data[2], pFrameYUV->linesize[2]);SDL_RenderClear( renderer );SDL_RenderCopy( renderer, bmp, &DisplayRect, &DisplayRect );SDL_RenderPresent( renderer );}//av_free_packet(packet);
}//Thread
int sfp_refresh_thread(void *opaque)
{SDL_Event event;VideoState *is = (VideoState *)opaque;printf("%s %d refresh thread id:%d !\n", __func__, __LINE__, is->refresh_tid);//while (is->refresh_tid != 0) //先把消息发过去,播放线程在等消息do{event.type = SFM_REFRESH_EVENT;SDL_PushEvent(&event);//Wait x msSDL_Delay(PLAY_REFRESH_TIME);}while(is->refresh_tid != 0);return 0;
}//调整同步时间
static double synchronize_video(VideoState *is, AVFrame *src_frame, double pts)
{double frame_delay;if (pts != 0) {/* if we have pts, set video clock to it */is->video_clock = pts;} else {/* if we aren't given a pts, set it to the clock */pts = is->video_clock;}/* update the video clock */frame_delay = av_q2d(is->video_st->codec->time_base);/* if we are repeating a frame, adjust clock accordingly */frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);is->video_clock += frame_delay;return pts;
}//音频处理
int audio_stream_component_open(VideoState *is, int stream_index)
{AVFormatContext *ic = is->VideoFormatCtx;AVCodecContext *codecCtx;AVCodec *codec;SDL_AudioSpec wanted_spec, spec;int64_t wanted_channel_layout = 0;int wanted_nb_channels;/*  SDL支持的声道数为 1, 2, 4, 6 *//*  后面我们会使用这个数组来纠正不支持的声道数目 */const int next_nb_channels[] = { 0, 0, 1, 6, 2, 6, 4, 6 };if (stream_index < 0 || stream_index >= ic->nb_streams) {return -1;}printf("%s %d entry !\n", __func__, __LINE__);packet_queue_init(&is->audioq);  //初始化音频队列
#if 0wanted_spec.format = AUDIO_S16SYS; // 具体含义请查看“SDL宏定义”部分wanted_spec.silence = 0;            // 0指示静音wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;  // 自定义SDL缓冲区大小wanted_spec.callback = audio_callback;        // 音频解码的关键回调函数wanted_spec.userdata = is;                    // 传给上面回调函数的外带数据do{is->audioID = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(0,0),0,&wanted_spec, &spec,0);printf("SDL_OpenAudio (%d channels): %s\n",wanted_spec.channels, SDL_GetError());wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];if (!wanted_spec.channels)	//逐个匹配频道{printf("No more channel combinations to tyu, audio open failed\n");
//            return -1;break;}}while(is->audioID == 0);SDL_PauseAudioDevice(is->audioID,0);
#endif#if 1///  打开SDL播放设备 - 开始SDL_LockAudio();wanted_spec.freq = is->aCodecCtx->sample_rate;wanted_spec.format = AUDIO_S16SYS;wanted_spec.channels = is->aCodecCtx->channels;wanted_spec.silence = 0;wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;wanted_spec.callback = audio_callback;wanted_spec.userdata = is;if(SDL_OpenAudio(&wanted_spec, &spec) < 0){fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());return -1;}SDL_UnlockAudio();SDL_PauseAudio(0); //开始播放
#endif
}//视频播放线程
int video_play(void *arg)
{//========SDL==========//SDL---------------------------int screen_w=0,screen_h=0;SDL_Window *screen; SDL_Renderer* sdlRenderer;SDL_Texture* sdlTexture;SDL_Rect sdlRect;int ret, got_picture;struct SwsContext *img_convert_ctx;SDL_Thread *refresh_tid;SDL_Event event; AVFrame 		*FrameVideo, *FrameYUV;int numBytes;uint8_t* out_buffer;AVPacket *packet;//=========SDL===end===VideoState *is = (VideoState *) arg;//初始化队列packet_queue_init(&is->videoq);printf("%s init video queue :%p\n", __func__, &is->videoq);//=============video====================FrameVideo = av_frame_alloc();FrameYUV = av_frame_alloc();printf("%s %d entry !\n", __func__, __LINE__);///解码后数据转成YUV420Pimg_convert_ctx = sws_getContext(is->vCodecCtx->width, is->vCodecCtx->height, is->vCodecCtx->pix_fmt, is->vCodecCtx->width, is->vCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);numBytes = avpicture_get_size(AV_PIX_FMT_YUV420P, is->vCodecCtx->width,is->vCodecCtx->height);out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));avpicture_fill((AVPicture *) FrameYUV, out_buffer, AV_PIX_FMT_YUV420P,is->vCodecCtx->width, is->vCodecCtx->height);//int y_size = is->vCodecCtx->width * is->vCodecCtx->height;//packet = (AVPacket *) malloc(sizeof(AVPacket)); //分配一个packet//av_new_packet(packet, y_size); //分配packet的数据packet = av_packet_alloc();screen_w = is->vCodecCtx->width;screen_h = is->vCodecCtx->height;printf("%s -- %d\n", __func__, __LINE__);if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  printf( "Could not initialize SDL - %s\n", SDL_GetError()); return -1;} //SDL 2.0 Support for multiple windows//创建窗口screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,screen_w, screen_h,SDL_WINDOW_OPENGL);if(!screen) {  printf("SDL: could not create window - exiting:%s\n",SDL_GetError());  return -1;}//创建一个渲染器sdlRenderer = SDL_CreateRenderer(screen, -1, 0);  //IYUV: Y + U + V  (3 planes)//YV12: Y + V + U  (3 planes)sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,is->vCodecCtx->width,is->vCodecCtx->height);  sdlRect.x=0;sdlRect.y=0;sdlRect.w=screen_w;sdlRect.h=screen_h;//================video===end===========//refresh_tid = SDL_CreateThread(sfp_refresh_thread, "play thread", NULL); //创建一个线程定时刷新is->refresh_tid = SDL_CreateThread(sfp_refresh_thread, "play thread", is); //创建一个线程定时刷新if(0 > is->refresh_tid){printf("video play create thread fail : %s\n", SDL_GetError());}while(1){//printf("%s %d loop\n", __func__, __LINE__);SDL_WaitEvent(&event);  //等待消息到来,再刷新//printf("%s %d\n", __func__, __LINE__);if(event.type==SFM_REFRESH_EVENT){//第三个参数改成0,会有这样的情况:当队列中刚好为空,还没来得及往队列中存包,导致播放器意外停止//如果改成1的话,会导致一直阻塞在读ideo pack中:SDL_CondWait(q->cond, q->mutex);if (packet_queue_get(&is->videoq, packet, 0) <= 0) {//printf("%s read pack end !\n", __func__);is->refresh_tid = 0;break;//队列里面没有数据了  读取完毕了}Video_Display_To_Window( 		is, packet,FrameVideo, FrameYUV,is->vCodecCtx, sdlTexture,sdlRenderer, img_convert_ctx,sdlRect);}}}

 

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 并发编程学习策略

    并发编程学习策略 01 | 学好并发两步曲1)跳出来,看全景 2)钻进去,看本质02 | 跳出来,看全景 1、导读1)从单一的知识和技术中“跳出来”,从全局看并发编程。 2)建立一张全景图,将并发编程抽象成三个核心问题:分工、同步、互斥。2、分工1)定义:所谓分工,类似于现实中…...

    2024/4/1 2:33:03
  2. C++面经

    C++面经之应届生找工作的“狗日”过程记录 .先附上我的座右铭: “不是因为看到希望才去坚持,而是坚持才会有希望。” . 吐槽一下: 2020注定是个苦逼年,坐标广州,对于我这种双非末流本科崽,真的是日了狗的难受,相信有些同学也会和我有过“温水煮青蛙”的经历,大学四年平…...

    2024/4/19 16:03:18
  3. 学习python的pygame模块尝试实现飞机大战游戏

    摘要 通过描述游戏的系统结构、代码实现模仿飞机大战,学习使用、安装pygame,用pygame模块中的sprite模块等技术开发一个有数据实时记录、动画效果、碰撞检测、音乐音效播放、暂停功能的弹幕射击游戏。 1.引言 本论文旨在学习使用pygame模块进行游戏开发作为python课程的期末…...

    2024/4/16 5:07:25
  4. vscode 左下角 select python interpret 设置无反应

    解决方案回退插件版本,我选的是2019.11.1更新的那个版本 vscode切换插件版本 以下记录vscode搭建python环境的两个坑。 最开始是下载完python配置好路径之后cmd运行python。 没有运行python而是打开了应用商店下载python的页面。 之后打开系统环境,发现用户路径有这个目录 C:…...

    2024/4/28 3:04:26
  5. 运行项目时候maven报错:maven-compiler-plugin:3.1:

    闲得无聊的时候从网上搜了个项目想做做玩,结果运行初期就报错如下,[INFO] Total time: 2.380 s [INFO] Finished at: 2020-07-08T22:53:03+08:00 [INFO] Final Memory: 10M/152M [INFO] ------------------------------------------------------------------------ [ERROR] F…...

    2024/4/16 5:07:35
  6. Java小白修炼手册--第五阶段--MyBatis框架

    目录MyBatisMyBatis框架简介什么是MyBatisMyBatis体系结构MyBatis框架的作用MyBatis配置文件框架API简介SqlSessionFactoryBuilderSqlSessionFactorySqlSessionMyBatis基本应用搭建MyBatis技术环境获取SqISession对象CRUD(增,删,改,查)操作利用SqISession实现CRUD操作利用MyBat…...

    2024/4/16 5:08:41
  7. 关于TCP 全连接队列的一些事情

    一、问题 今天有个小伙伴跑过来告诉我有个奇怪的问题需要协助下,问题确实也很奇怪。客户端调用RT比较高并伴随着间歇性异常Connection reset出现,而服务端CPU 、线程栈等看起来貌似都很正常,而且服务端的RT很短。 这里先说下结果: 因为TCP全连接队列太小导致的连接被丢弃,…...

    2024/4/20 1:05:10
  8. 百度上传个人资料可以这样做

    在信息快速发展的今天,很多的人随着知名度的提高,都在网上有了自己的信息,但这些信息怎么做上去的呢,相信很多人都想知道,先不说已经在网上展现的那些个人信息,更多的人比较关注百度上传个人资料怎样才能做上去,下面小编简单的说下用哪些方式可以把自己的信息做到百度上…...

    2024/4/1 2:32:56
  9. 秋季招聘季如何制作一款“秀色可餐”的简历?由ShareLatex和Python3打造

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_161 秋招季还有两个月就到了,即所谓的“金九银十”。疫情因素导致市场环境不太理想,所以我们更应该未焚而徙薪,未雨而绸缪,提前做好准备,否则到了时候才临渴掘井、江心补漏那就真的来不及了,而找工作的第一步就是写简历…...

    2024/4/18 1:20:52
  10. 游戏策划笔记:战斗手感

    7/8 今天收获了实习offer,快乐 https://www.gcores.com/articles/105816 战斗手感,阅读笔记。 打击感的前提:攻击动作让其他事物的状态改变 攻击使敌人动作改变,意义不仅是一个感官反馈,更是在于逻辑上——被命中的敌人进入动作状态机中的“受伤”片段,受伤过程中还有可能…...

    2024/4/16 5:06:29
  11. Gartner发布2020年数据与分析领域的十大技术趋势道翰天琼认知智能未来机器人接口API

    近日,Gartner发布了数据与分析领域的十大技术趋势,为数据和分析领导者的新冠疫情(COVID-19)响应和恢复工作提供指导,并为疫情后的重启做好准备。数据和分析领导者如果希望在疫情后能持续创新,就需要不断提高数据处理和访问的速度,扩大分析规模,在前所未有的市场动荡中赢…...

    2024/4/19 2:41:58
  12. 面试题—Kubernetes(二)

    1.K8S三种方式 K8S三种方式 专有版 Kubernetes 托管版 Kubernetes Serverless Kubernetes2.Master选择 1-5个节点 4核8G(不建议2核4G) 6-20个节点 4核16G 21-100个节点 8核32G 100-200个节点 16核64G3.Service 有四种类型 Service 有四种类型: ClusterIP NodePort LoadBalance…...

    2024/4/18 22:22:06
  13. HTTP访问控制(CORS)——预检请求问题的解决

    文章目录1:CORS介绍2:什么情况下需要 CORS3:跨域资源共享机制功能概述3.1 若干访问控制场景案例演示3.1.1 预检请求4:实际问题中解决预检请求案例演示 1:CORS介绍CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头…...

    2024/4/16 20:36:20
  14. Redis的雪崩、击穿、穿透

    一 穿透优化1.1 缓存穿透概念缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,通常出于容错的考虑,如果从存储层拿不到数据就不写入缓存层。整个过程是:缓存层没有命中存储层没有命中,不将空结果写入缓存返回空结果缓存穿透将导致不存在的数据每次请求都要…...

    2024/4/25 19:11:14
  15. Python-人脸识别检测是否佩戴口罩 使用口罩数据集

    本博客运行环境为jupyter下python3.6 完成对口罩佩戴与否的模型训练,采取合适的特征提取方法,输出模型训练精度和测试精度(F1-score和ROC);完成一个摄像头采集自己人脸、并能实时分类判读(输出分类文字)的程序。 环境搭建可参看上一篇博客:https://blog.csdn.net/weixi…...

    2024/4/16 5:06:59
  16. Leetcode 6.Z 字形变换

    Leetcode 6.Z 字形变换题目失败的代码题解 题目将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下: L C I R E T O E S I I G E D H N 之后,你的输出需要从左往右逐行读取,…...

    2024/4/16 5:06:39
  17. tensorflow, keras, Tokenizer 获取文本信息, NLP

    Tokenizer是keras.preprocessing.text包下的一个类,调用路径为:tensorflow.keras.preprocessing.text.Tokenizer.tensorflow和keras就以其数不清的包而著称,也为其诟病。Tokenizer是在数据预处理的时候常用的一个类,其作用是:在处理文本时候向量化整个文本库。接触过机器学…...

    2024/4/16 5:07:30
  18. 注解与反射_anno

    1、概念 JDK1.5之后的新特性 说明程序的 使用注解(Annotation),也叫元数据:@注解名称 与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。 2、作用分类:①编写文档:通过代码里标识的注解生成…...

    2024/4/16 5:07:40
  19. 12 Java中的ArrayList

    import java.util.ArrayList;/*** 1. size() 获取ArrayList里面的元素个数* 2. add() 有返回值,对于ArrayList来说,这个方法一定会执行成功* 因此返回值是true* 3. get(int index) index是从0开始的* 4. remove(int index) 会返回被remove的元素*/ public class LearnArrayLi…...

    2024/4/16 5:07:45
  20. Python3 随机数模块 random

    取随机小数 import random# 用于生成一个0到1的随机浮点数:0<= n < 1.0 num1 = random.random() # 用于生成一个指定范围内的随机浮点数,两个参数其中一个是上限,一个是下限。如果 a > b,则生成的随机数 n: b <= n <= a。如果 a < b, 则 a <= n <…...

    2024/4/16 5:08:26

最新文章

  1. javaScript基础2

    javaScript 一.运算符二.流程控制1.顺序流程控制2.分支流程控制&#xff08;1&#xff09;if/if..else/if多分支&#xff08;2&#xff09;.三元表达式&#xff08;4&#xff09;.switch和if else区别 3.循环流程控制(1).for循环/双重for循环(2).一些例子(3).while循环/do..whi…...

    2024/4/28 3:55:45
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. uos安装lxml避坑记录

    环境&#xff1a;紫光电脑uos系统 python&#xff1a;系统自带3.7.3 条件&#xff1a;已打开开发者模式&#xff0c;可以自行安装应用商店之外的软件 一、pip3 install lxml4.8.0可以正正常下载&#xff0c;但出现如下错误 另&#xff1a;为什么是4.8.0&#xff1f;因为这个…...

    2024/4/27 8:52:59
  4. Ubuntu磁盘扩容

    使用 df -h命令查看系统磁盘控件的使用情况&#xff1a; [samspobosrv:~]$ df -h Filesystem Size Used Avail Use% Mounted on udev 7.8G 0 7.8G 0% /dev tmpfs 1.6G 1.7M 1.…...

    2024/4/25 7:31:32
  5. OpenHarmony开发-连接开发板调试应用

    在 OpenHarmony 开发过程中&#xff0c;连接开发板进行应用调试是一个关键步骤&#xff0c;只有在真实的硬件环境下&#xff0c;我们才能测试出应用更多的潜在问题&#xff0c;以便后续我们进行优化。本文详细介绍了连接开发板调试 OpenHarmony 应用的操作步骤。 首先&#xf…...

    2024/4/27 20:51:51
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/26 18:09:39
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/28 3:28:32
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/26 23:05:52
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/27 4:00:35
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/27 9:01:45
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/28 1:22:35
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/25 18:39:00
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/26 19:46:12
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/27 11:43:08
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/27 8:32:30
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57