应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

Android硬编解码MediaCodec解析从猪肉餐馆的故

  上篇回顾
  前面两篇文章Android硬编解码MediaCodec解析从猪肉餐馆的故事讲起(一)和Android硬编解码MediaCodec解析从猪肉餐馆的故事讲起(二)已经从猪肉餐馆的故事带各位比较详细地阐述了Android平台硬解码工具MediaCodec的工作流程和具体的代码,但是前两篇文章的分析是基于静态的,但是MediaCodec具体的解码流程是怎么样的,我们并不知道。那么今天就让代码动起来,通过log和辅助代码去更加深入掌握MediaCodec的解码流程。
  如果还没看过前面两篇博文,还是建议看一下,因为本文和前两篇是有很大关联的。
  代码运行log分析
  首先点击第一个item:
  进入到这个界面:
  看下此时的Log:
  log打印位置在com。android。grafika。PlayMovieActivity,主要看下SurfaceTextureready(984x1384)这一行:OverridepublicvoidonSurfaceTextureAvailable(SurfaceTexturest,intwidth,intheight){TheresashortdelaybetweenthestartoftheactivityandtheinitializationoftheSurfaceTexturethatbackstheTextureView。WedontwanttotrytosendavideostreamtotheTextureViewbeforeithasinitialized,sowedisabletheplaybuttonuntilthiscallbackfires。Log。d(TAG,SurfaceTextureready(widthxheight));mSurfaceTextureReadytrue;updateControls();}
  还记得Android硬编解码工具MediaCodec解析从猪肉餐馆的故事讲起(二)画的整体流程图么:
  onSurfaceTextureAvailable这个回调方法就是告诉我们,TextureView的SurfaceTexture已经初始化好了,可以开始渲染了。此时才会将播放按钮置为可点击。logSurfaceTextureready(984x1384)中的(984x1384)即为TextureView的尺寸。
  C学习资料免费获取方法:关注音视频开发T哥,链接即可免费获取2023年最新C音视频开发进阶独家学习资料!
  此时,轻轻点击播放按钮,于是视频开始动起来了,可谓是穿梭时间旳画面的钟,从反方向开始移动:
  首先输出了这条log:
  DfuyaoGrafika:Extractorselectedtrack0(videoavc):{trackid1,level32,mimevideoavc,profile1,language,colorstandard4,displaywidth320,csd1java。nio。HeapByteBuffer〔pos0lim8cap8〕,colortransfer3,durationUs2033333,displayheight240,width320,colorrange2,maxinputsize383,framerate16,height240,csd0java。nio。HeapByteBuffer〔pos0lim38cap38〕}
  它是在MediaExtractor选中媒体轨道的时候打印的,打印出具体当前视频轨道格式相关信息:Selectsthevideotrack,ifany。returnthetrackindex,or1ifnovideotrackisfound。privatestaticintselectTrack(MediaExtractorextractor){Selectthefirstvideotrackwefind,ignoretherest。当前媒体文件共有多少个轨道(视频轨道、音频轨道、字幕轨道等等)intnumTracksextractor。getTrackCount();for(inti0;inumTracks;i){第i个轨道的MediaFormatMediaFormatformatextractor。getTrackFormat(i);format对应的mime类型Stringmimeformat。getString(MediaFormat。KEYMIME);找到视频轨道的indexif(mime。startsWith(video)){if(VERBOSE){注意这行的log打印Log。d(TAG,Extractorselectedtracki(mime):format);}returni;}}return1;}
  稍微解释下log中的几个关键参数:
  1。log中的level和profile指的是画质级别,以下解释引用于H264编码profilelevel控制
  H。264有四种画质级别,分别是baseline,extended,main,high:1、BaselineProfile:基本画质。支持IP帧,只支持无交错(Progressive)和CAVLC;2、Extendedprofile:进阶画质。支持IPBSPSI帧,只支持无交错(Progressive)和CAVLC;(用的少)3、Mainprofile:主流画质。提供IPB帧,支持无交错(Progressive)和交错(Interlaced),也支持CAVLC和CABAC的支持;4、Highprofile:高级画质。在mainProfile的基础上增加了8x8内部预测、自定义量化、无损视频编码和更多的YUV格式;H。264Baselineprofile、Extendedprofile和Mainprofile都是针对8位样本数据、4:2:0格式(YUV)的视频序列。在相同配置情况下,Highprofile(HP)可以比Mainprofile(MP)降低10的码率。根据应用领域的不同,Baselineprofile多应用于实时通信领域,Mainprofile多应用于流媒体领域,Highprofile则多应用于广电和存储领域。
  2。mime为videoavc,这个上篇文章已经讲过,videoavc即为H264。
  3。colorstandard:指的是视频的颜色格式,Anoptionalkeydescribingthecolorprimaries,whitepointandluminancefactorsforvideocontent。Theassociatedvalueisaninteger:0ifunspecified,oroneoftheCOLORSTANDARDvalues。publicstaticfinalStringKEYCOLORSTANDARDcolorstandard;BT。709colorchromacitycoordinateswithKR0。2126,KB0。0722。publicstaticfinalintCOLORSTANDARDBT7091;BT。601625colorchromacitycoordinateswithKR0。299,KB0。114。publicstaticfinalintCOLORSTANDARDBT601PAL2;BT。601525colorchromacitycoordinateswithKR0。299,KB0。114。publicstaticfinalintCOLORSTANDARDBT601NTSC4;BT。2020colorchromacitycoordinateswithKR0。2627,KB0。0593。publicstaticfinalintCOLORSTANDARDBT20206;
  还记得音视频开发基础知识之YUV颜色编码里面说过,RGB到YUV有不同的转化标准:目前一般解码后的视频格式为yuv,但是一般显卡渲染的格式是RGB,所以需要把yuv转化为RGB。
  这里涉及到ColorRange这个概念。ColorRange分为两种,一种是FullRange,一种是LimitedRange。FullRange的R、G、B取值范围都是0255。而LimitedRange的R、G、B取值范围是16235。
  而对于每种ColorRange来说,还有不同的转换标准,常见的标准主要是BT601和BT709(BT601是标清的标准,而BT709是高清的标准)。
  这里该视频的colorstandard为4,即转换标准为BT。601525。
  4。colorrange:上面引用部分已经提及,当前colorrange为2,看下谷歌文档的常量值说明:Limitedrange。Ycomponentvaluesrangefrom16to235for8bitcontent。Cr,Cyvaluesrangefrom16to240for8bitcontent。Thisisthedefaultforvideocontent。publicstaticfinalintCOLORRANGELIMITED2;Fullrange。Y,CrandCbcomponentvaluesrangefrom0to255for8bitcontent。publicstaticfinalintCOLORRANGEFULL1;
  所以当前视频的colorrange为Limitedrange。
  其他参数因为数量太多,大家也大部分可以看明白,就不一一解释了。
  看接下来的log:
  第一行是这里打印的:拿到可用的ByteBuffer的indexintinputBufIndexdecoder。dequeueInputBuffer(TIMEOUTUSEC);根据index得到对应的输入ByteBufferByteBufferinputBufdecoderInputBuffers〔inputBufIndex〕;Log。d(TAG,decoderInputBuffersinputBuf:inputBuf,inputBufIndex:inputBufIndex);
  打印的是inputBuffer的情况,上一篇已经讲过,这里就如同生猪肉采购员询问厨师有没有空篮子,厨师在TIMEOUTUSEC微秒时间内告诉了采购员篮子的编号,然后采购员根据编号找到对应的空篮子。
  根据log可以看出:
  decoderInputBuffersinputBuf:java。nio。DirectByteBuffer〔pos0lim6291456cap6291456〕,inputBufIndex:2
  这个空Buffer大小为6291456字节(pos表示当前操作指针指向的位置,lim表示当前可读或者可写的最大数量,cap表示其容量),inputBufIndex为2,即该Buffer在MediaCodec的输入Buffer数组的位置是2。
  submittedframe0todec,size339
  这个log的frame0表示MediaExtractor的readSampleData读取出来的第几块数据,在这里就是第几帧,size339表示该帧大小为339字节,当然这是压缩的数据大小。
  下面一条log输出端取数据的,即顾客询问厨师猪肉炒好了没有:
  DfuyaoGrafika:dequeueOutputBufferdecoderBufferIndex:1,mBufferInfo:android。media。MediaCodecBufferInfofcbc6e2
  DfuyaoGrafika:nooutputfromdecoderavailable
  这条log来源:intoutputBufferIndexdecoder。dequeueOutputBuffer(mBufferInfo,TIMEOUTUSEC);Log。d(TAG,dequeueOutputBufferdecoderBufferIndex:outputBufferIndex,mBufferInfo:mBufferInfo);
  decoderBufferIndex为1,则等于MediaCodec。INFOTRYAGAINLATER,即当前输出端还没有数据,即厨师告诉顾客,猪肉还没做好。
  如果看过之前我写的解析H264视频编码原理从孙艺珍的电影说起(一)和解析H264视频编码原理从孙艺珍的电影说起(二),就知道视频编码是一个非常复杂的过程,涉及大量的数学算法,所以解码也不会简单,基本不会刚放一帧数据到input端,output端就立马拿到解码后的数据。
  从后面的log可以看到,经过很多次在input端放入数据,又尝试在output端取出数据的循环之后,终于在第一次在input端放入数据的77ms秒之后,在output端拿到了数据:
  startuplag是官方demo已经有的统计从第一次在input端放入数据到第一次从output端拿到数据的时间长。
  接下来就是取到具体数据的log:
  decoderBufferIndex为0,即取到的解码数据所在的buffer在output端buffer数组第0个。
  ecoderOutputBuffers。length:8是我专门把output数组数量打印出来:ByteBuffer〔〕decoderOutputBuffersdecoder。getOutputBuffers();Log。d(TAG,ecoderOutputBuffers。length:decoderOutputBuffers。length);
  可见output端buffer数组大小为8个(经过实践发现,该数值并不是固定的)。
  outputBuffer:java。nio。DirectByteBuffer〔pos0lim115200cap115200〕表示该buffer的可用数据和容量都为115200。后面解码出来的数据也是这个大小,因为解码之后的数据就是一帧画面的yuv数据,因为画面的分辨率固定,yuv格式也是固定,所以大小自然也是一样的。
  而在output拿到数据之前的上一次取数据的log需要注意下:
  DfuyaoGrafika:dequeueOutputBufferdecoderBufferIndex:2,mBufferInfo:android。media。MediaCodecBufferInfo9bec00c
  DfuyaoGrafika:decoderoutputformatchanged:{cropright319,colorformat21,sliceheight240,imagedatajava。nio。HeapByteBuffer〔pos0lim104cap104〕,mimevideoraw,stride320,colorstandard4,colortransfer3,cropbottom239,cropleft0,width320,colorrange2,croptop0,height240}
  decoderBufferIndex为2,即MediaCodec。INFOOUTPUTFORMATCHANGED。在拿到数据之后,会现有一个通知输出数据格式变化的通知,我们可以在这里拿到输出数据的格式。
  1。cropleft0,cropright319,croptop0,cropbottom239表示的是真正的视频区域的4个顶点在整个视频帧的坐标位置。
  有读者可能会问,视频不是充满一帧么?其实不是的,看下官网的解读developer。android。google。cnreferencea:TheMediaFormatKEYWIDTHandMediaFormatKEYHEIGHTkeysspecifythesizeofthevideoframes;however,formostencondingsthevideo(picture)onlyoccupiesaportionofthevideoframe。Thisisrepresentedbythecroprectangle。
  Youneedtousethefollowingkeystogetthecroprectangleofrawoutputimagesfromtheoutputformat。Ifthesekeysarenotpresent,thevideooccupiestheentirevideoframe。Thecroprectangleisunderstoodinthecontextoftheoutputframebeforeapplyinganyrotation。
  具体key的意义:
  FormatKey
  Type
  Description
  MediaFormatKEYCROPLEFT
  Integer
  Theleftcoordinate(x)ofthecroprectangle
  MediaFormatKEYCROPTOP
  Integer
  Thetopcoordinate(y)ofthecroprectangle
  MediaFormatKEYCROPRIGHT
  Integer
  Therightcoordinate(x)MINUS1ofthecroprectangle
  MediaFormatKEYCROPBOTTOM
  Integer
  Thebottomcoordinate(y)MINUS1ofthecroprectangle
  官网又给了一段通过这4个值计算视频有效区域的代码:MediaFormatformatdecoder。getOutputFormat();intwidthformat。getInteger(MediaFormat。KEYWIDTH);if(format。containsKey(MediaFormat。KEYCROPLEFT)format。containsKey(MediaFormat。KEYCROPRIGHT)){widthformat。getInteger(MediaFormat。KEYCROPRIGHT)1format。getInteger(MediaFormat。KEYCROPLEFT);}intheightformat。getInteger(MediaFormat。KEYHEIGHT);if(format。containsKey(MediaFormat。KEYCROPTOP)format。containsKey(MediaFormat。KEYCROPBOTTOM)){heightformat。getInteger(MediaFormat。KEYCROPBOTTOM)1format。getInteger(MediaFormat。KEYCROPTOP);}
  2。colorformat:颜色编码格式。21即为COLORFormatYUV420SemiPlanar,也常叫做叫作NV21。关于yuv具体格式在音视频开发基础知识之YUV颜色编码已有叙述,不过文章并没有具体讲NV21,NV21的于半平面格式(semiplanner),y独立放一个数组,uv放一个数组,先V后U交错存放(图来自:浅析YUV颜色空间)
  比如一个44的画面,分布如下图所示:YYYYYYYYYYYYYYYYVUVUVUVU
  3。sliceheight:指的是帧的高度,即有多少行,不过这个行数可能是内存对齐过的,有时候为了提高读取速度,视频帧高度会填充到2的次幂数值。
  4。stride:跨距,是图像存储的时候有的一个概念。它指的是图像存储时内存中每行像素所占用的空间。同样的,这个也是经过内存对齐的,所以是大于等于原视频的每行像素个数。很多视频花屏问题的根源就是忽略了stride这个属性。
  其他参数上面已讲过,就不赘述。
  拿到输出的解码数据就通过releaseOutputBuffer渲染到Surface:将输出buffer数组的第outputBufferIndex个buffer绘制到surface。doRender为true绘制到配置的surfacedecoder。releaseOutputBuffer(outputBufferIndex,doRender);
  我们看到log的output最后一帧数据是:
  outputEOS
  当调用:intoutputBufferIndexdecoder。dequeueOutputBuffer(mBufferInfo,TIMEOUTUSEC);
  得到的mBufferInfo。flags为MediaCodec。BUFFERFLAGENDOFSTREAM(intput端在视频最后一帧的时候传入)的时候,说明该帧已经是视频最后一帧了,此时就跳出解码的大循环,准备释放资源:finally{releaseeverythingwegrabbedif(decoder!null){Callstop()toreturnthecodectotheUninitializedstate,whereuponitmaybeconfiguredagain。decoder。stop();decoder。release();decodernull;}if(extractor!null){extractor。release();extractornull;}}
  还记得Android硬编解码利器MediaCodec解析从猪肉餐馆的故事讲起(一)提及过得MediaCodec的状态机么:
  先调用了stop方法,就进入了Uninitialized状态,即猪肉餐馆要收拾桌椅了,收拾完桌椅之后,再调用release就释放资源,即猪肉餐馆关门了。将解码输出数据保存下来
  接下来来做一件有趣的事情,就是将每次输出的解码数据保存为图片。
  创建一个方法接收输出的一帧数据,然后通过系统提供的YuvImage可以将yuv数据转化为jpeg数据,然后通过BitmapFactory。decodeByteArray将jpeg数据转化为Bitmap,再保存到本地文件夹中。privatevoidoutputFrameAsPic(byte〔〕ba,inti){Log。d(TAG,outputBufferi:i);YuvImageyuvImagenewYuvImage(ba,ImageFormat。NV21,mVideoWidth,mVideoHeight,null);ByteArrayOutputStreambaosnewByteArrayOutputStream();将yuv转化为jpegyuvImage。compressToJpeg(newRect(0,0,mVideoWidth,mVideoHeight),100,baos);byte〔〕jdatabaos。toByteArray();rgbBitmapbmpBitmapFactory。decodeByteArray(jdata,0,jdata。length);if(bmp!null){try{FileparentnewFile(Environment。getExternalStorageDirectory()。getAbsolutePath()moviePlayer);if(!parent。exists()){parent。mkdirs();}FilemyCaptureFilenewFile(parent。getAbsolutePath(),String。format(imgs。png,i));if(!myCaptureFile。exists()){myCaptureFile。createNewFile();}BufferedOutputStreambosnewBufferedOutputStream(newFileOutputStream(myCaptureFile));bmp。compress(Bitmap。CompressFormat。JPEG,80,bos);Log。d(TAG,bmp。compressmyCaptureFile:myCaptureFile。getAbsolutePath());bos。flush();bos。close();}catch(Exceptione){e。printStackTrace();Log。d(TAG,outputFrameAsPicException:e);}}}
  然后在每次获得output端Buffer的地方调用该方法:ByteBufferoutputBufferdecoderOutputBuffers〔outputBufferIndex〕;Log。d(TAG,outputBuffer:outputBuffer);outputBuffer。position(mBufferInfo。offset);outputBuffer。limit(mBufferInfo。offsetmBufferInfo。size);byte〔〕banewbyte〔outputBuffer。remaining()〕;byteBuffer数据放入baoutputBuffer。get(ba);输出的一帧保存为本地的一张图片outputFrameAsPic(ba,decodeFrameIndex);
  再运行下程序,得到以下图片:
  可见每一帧都成功截图并保存到本地同步与异步模式
  最后说下,MediaCodec编解码是分为同步和异步模式的(Android5。0开始支持异步状态),同步就是比如生猪肉采购员和顾客必须在Android硬编解码工具MediaCodec解析从猪肉餐馆的故事讲起(二)的关于MediaCodec的解码流程代码,是属于同步,所谓的同步,是相对于异步而言的。同步和异步最大的不同,个人认为就是前者是要求我们主动去咨询MeidaCodec有没有可用的Buffer可以用,后者是MeidaCodec来通知我们已经有有了可用的buffer。就像原来是猪肉采购员主动询问厨师有没有空篮子可以用,现在变为厨师发个微信告诉采购员现在有空篮子可以用。
  对于异步来说,MediaCodec的工作状态和同步有一点不同:
  异步的情况下从Configured会直接进入Running状态,然后等待MediaCodec的回调通知再处理数据即可,以下为官方给的代码模板:MediaCodeccodecMediaCodec。createByCodecName(name);MediaFormatmOutputFormat;membervariablecodec。setCallback(newMediaCodec。Callback(){OverridevoidonInputBufferAvailable(MediaCodecmc,intinputBufferId){ByteBufferinputBuffercodec。getInputBuffer(inputBufferId);fillinputBufferwithvaliddatacodec。queueInputBuffer(inputBufferId,);}OverridevoidonOutputBufferAvailable(MediaCodecmc,intoutputBufferId,){ByteBufferoutputBuffercodec。getOutputBuffer(outputBufferId);MediaFormatbufferFormatcodec。getOutputFormat(outputBufferId);optionAbufferFormatisequivalenttomOutputFormatoutputBufferisreadytobeprocessedorrendered。codec。releaseOutputBuffer(outputBufferId,);}OverridevoidonOutputFormatChanged(MediaCodecmc,MediaFormatformat){Subsequentdatawillconformtonewformat。CanignoreifusinggetOutputFormat(outputBufferId)mOutputFormatformat;optionB}OverridevoidonError(){}});codec。configure(format,);mOutputFormatcodec。getOutputFormat();optionBcodec。start();waitforprocessingtocompletecodec。stop();codec。release();总结
  本文在上一文章分析代码的基础上运行了代码,通过分析log分析解码流程的细节,让各位对解码流程有更清晰的认识。并将解码出来的每帧截图保存到本地,验证了视频解码的output端每次获取的数据确实是表示一帧的数据。
  最后讲了一下MediaCodec编解码异步模式相关。
  美好的时光总是过得很快,不知不觉已经用了三篇博文讲MediaCodec了,我已经迫不及待地想进入下一个系列了OpenGL系列。
  因为解码成功后,就是渲染到屏幕了,而当前Android平台最主流的渲染工具,就是OpenGL了。
  作者:半岛铁盒里的猫链接:https:juejin。cnpost7113767096512675870来源:稀土掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  在开发的路上你不是一个人,欢迎加入C音视频开发交流群大家庭正在跳转讨论交流
  程序员C音视频开发

一加N300将于下个月发布,支持33W快充IT之家10月13日消息,一加透露了部分有关其即将推出的NordN300的细节,该机将支持33W有线充电。一加发言人SpenserBlank表示,该设备将于下个月登陆北美市场,……周鹏庆33岁生日,转会深圳,儿女双全,1米87老婆很漂亮CBA联盟近些年来发展越来越好,球员的表现同样越来越出色。说到联盟的豪强,广东队可以说是最为成功的,他们冠军拿到手软,也培养了许多伟大的球星,像杜锋、易建联、朱芳雨、王仕鹏、周……8月新能源轿车销量排行榜,比亚迪海豚暴涨,长安Lumin首次近日,乘联会发布2022年8月份新能源轿车销量排行榜前15名,整体看排行榜销量全部呈现增长趋势,其中,比亚迪海豚增幅最多,达77560;五菱宏光MINIEV增幅最少,仅有3。1……社会价值正成为决定企业未来的关键因素专访朱睿教授对于很多长江同学来说,社会创新课程都是一份独特且印象深刻的经历。从2016年长江于全球率先引入社会创新课程,到2018年成为必修课、成为长江商学院开学第一课,再到2021……行吟诗刊丨张家界用群山写一首浩荡而锋利的诗咏洲摄张家界:用群山写一首浩荡而锋利的诗(组诗)作者丨阿雅在张家界山有傲骨,云有美色空气被大雪滤过那些悬崖和悬崖上的树木教会我挺直胸膛……亿万富豪白手起家创业成功的12个秘密周末回家,瓜妈向我推荐了一部美国的真人秀节目,叫《亿万富豪谷底大翻身》她已记不清以前是在哪里看的,但却非常隆重地向我推荐,说这部片子绝对很值得我看看,并表示,可以泡茶作伴……世界500强再落一子!日本爱信集团在南海投放汽车电动化产线世界500强爱信集团在南海落地第三个项目。12月15日,爱信(佛山)车身零部件有限公司(下称爱信车身)新能源汽车电动化零部件生产项目签约落子南海。该项目固定资产投资3亿元……行事痿软,取三仁汤开上,宣中,渗下,三焦通达,则百脉皆通我的一位患者,温先生,41岁,主诉行事痿软。患者体质肥胖,来诊时可见面色萎黄,自述曾长时间服用壮阳补肾药,收获甚微。如今症见:大欲淡漠,气短乏力,胸闷院痞,肢倦身重,舌质……人品好的人都有3个特征,遇到了,请深交一辈子人这一辈子交朋友,可以选择有钱有势的,也可以选择有共同话题的。还有一点很重要:那就是选人品好的人,做朋友。人品不好,你要是还跟他当朋友,那迟早被他卖了,还要帮他数钱……独裁者埃隆马斯克,对推特上批评他的人搞文字狱当美国人发现批评推特老板埃隆马斯克的知名媒体被禁止进入该平台时,推特上目前一片混乱。被永久封禁账户的包括CNN记者多尼奥沙利文、《纽约时报》科技记者瑞安麦克、《华盛顿邮报……前列腺炎,只是难治的小病,做到4点,治愈不过是易如拾芥要说前列腺炎难治,确实,难在三点:1。长期使用大量抗生素药物及苦寒清利药物,失治、误治导致前列腺炎症状加重、反复。2。长期得不到治愈及一些不正确的误导,使得患者抑郁……格林招募德罗赞,骑士面临二选一,詹姆斯释放信号美媒爆料上赛季格林和德罗赞的互动,骑士目前在续约上似乎有了选择,詹姆斯在自己合同还剩一年时释放信号。格林曾招募德罗赞被大骂拒绝据美媒报道,德拉蒙德格林在2021赛季……
中国十大火炉城市有网友经常问我,在夏天旅游,你就不怕炎热吗?这个问题我还真没仔细想过。不过,猛然想起来,有些地方真象火炉蒸馒头,让人受不了。夏天徒步过几次全长13。76千米的西安城墙,太阳直射……没有街舞的夏天是不完整的,今年也是作者谢明宏编辑李春晖夏季是各类剧集综艺的主战场,也是收视争夺最激烈的时段。作为一个追了五年《这!就是街舞》的老粉,硬糖君实在想不避嫌疑地安利下有了街舞,夏天才算真正……巴黎内讧!姆巴佩被推上风口浪尖,巴黎后悔没有放人了吗?姆巴佩被推上风口浪尖,在最新的法甲比赛中出现的消息态度,以及与内马尔的点球权争夺。202223赛季法甲第二轮比赛刚过,巴黎圣日耳曼就爆出内讧,姆巴佩与内马尔被有关媒体描述为水火……湖人队你们最想让走的人终于走了在篮网彻底结束自己的闹剧之后,属于湖人的时刻终于来了!湖人用塔克斯坦利约翰逊换来了贝弗利,并且交易不涉及选秀权!这一波操作属实让人振奋啊!想想塔克去年的表现,那真是……隐退12年复出,就这演技?大约一周前,由孙莉主演的电视剧《妻子的选择》正式上线,以准黑马之姿加入到中偶剧的混战行列。这是孙莉时隔十二年的荧屏之作。在此之前,她多以黄磊妻子多多妈妈等演员以外的……斯诺克排名塞尔比跌出前三丁俊晖赵心童双双下滑曹宇鹏保级无忧北京时间8月22日凌晨,斯诺克2022欧洲大师赛在德国柏林终于落下帷幕,小天王凯壬威尔逊在与巴里霍金斯的冠军争夺战中笑到最后,最终以总比分93狂扫对手斩获个人职业生涯第5座排名……红米note10pro记录生活2021年10月这部红米note10pro是去年10底买的,用来取代华为Mate10,一部入门机与中阶机相差两年多,基本上是完胜了,数码产品就是如此,越晚推出的就先进越完善越强悍。而且随着年纪……C罗再引争议!不满绯闻前中超锋霸,质疑曼联雄心,持续寻找下家新赛季的英超联赛,曼联一上来就吃到闭门羹,主场12不敌布莱顿,爆出冷门。如同传闻中的一样,一直想要离队的C罗开始担任替补,他在球队02落后的情况下登场,很遗憾没有能够力挽狂澜,……华为花粉俱乐部宣布停运原有相关数据合并到我的华为AppTech星球8月8日消息,今天华为花粉俱乐部发布了关于花粉俱乐部运营服务调整的公告。表示,因业务发展调整,花粉俱乐部原有相关数据(包含但不限于用户的已发布帖子、评论、勋章、关注……最强黑马翻车!4连胜被升班马终结,输球输人下轮咋阻击三镇?最强黑马翻车!河南嵩山龙门主场01不敌梅州客家,4连胜被终结,也遭遇了赛季第二场败仗,罗歆更是因为不理智动作染红。而下场,河南队将迎战武汉三镇,如此阵容状态恐无法阻击三镇,最强……阿里京东唯品会集体转身,电商风向变了京东、唯品会干着同一件事唯品会正在打破消费者的固有认知。过去,只有在买衣服鞋子的时候,大家才会想起唯品会。近日,有不少网友发现唯品会不止卖衣服,还卖化妆品、手……解决机身厚重难题小米MIXFold2证明折叠屏手机也可以很轻虽然现在各大手机厂商都已经推出了各自的折叠屏手机产品,但我们在日常生活中很少见到有人用折叠屏手机。除了价格因素之外,折叠屏手机过于厚重、不便于携带也是用户较少的主要原因。毕竟折……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网