专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

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取值范围都是0~255。而LimitedRange的R、G、B取值范围是16~235。
  而对于每种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音视频开发

蒲公英巧搭一味,不仅清热解毒,还能清肝明目滋阴补肾健脾消食大家好,我是李医生,说起蒲公英,我们知道它可以清热解毒,像生活中经常上火的人,就都喜欢饮用蒲公英泡水来清热,但是你知道吗?蒲公英巧搭一味,除了清热解毒之外,还能清肝明目滋阴补肾健脾4个方法教你如何增强体质,简单实用春季甲流肆虐,今年的甲流来势汹汹,学校刚开学又不得不先暂时停课,学生及老年人又成为重点防护人群。现在为大家提供4种防疫毒的有效方法,可以有效预防提高自身体质。一轻叩膻中畅胸阳黄帝内柴胡疏肝散还能治疗5种病,头痛心痛胁痛腹痛功能下降大家好,我是胡医生。柴胡疏肝散可以疏肝理气活血止痛。还可以调理以下5种病,头痛心口疼两侧肋部疼肚子疼功能下降等。第一个,头痛。柴胡疏肝散可以调理因肝气郁结导致的头痛,这种头痛很有特清华研究糖会让你脱发!警惕这5种不甜的含糖食物,你肯定吃过点击右上方红色关注,及时获取我们为您推送的健康资讯清华研究含糖饮料喝得越多,中国男性型脱发风险越高。2023年1月,清华大学的研究者们在期刊发表了一项最新研究,结果显示,含糖饮料喝脾胃不好,不吃药,怎么改善呢?跟我学养生,健康又轻松,大家好,我是中医李大夫。今天继续给大家来分享穴位的妙用。很多脾胃不好的人都会有,没胃口,一吃就饱,经常胃痛,胃胀,口气异常,腹泻等情况。基本原因为饮食不健康生吃补肾,熟吃健脾!中老年人每天吃几粒,强壮筋骨,腰也不疼了大家好,这里是小橘寻美食!年纪越大,腰腿越不好,稍微干一点重的活,就会浑身酸痛,腰疼脚疼,像我爸就有这种问题,每次都要缓上两三天才能好。实在忍受不了疼痛,只能靠药物医治,或者去医院3鱼腩球队竞争基石!文班亚马去哪队更舒服?首选马刺或更舒服勒布朗詹姆斯布雷克格里芬锡安威廉姆森和维克托文班亚马被认为是过去20多年时间里最被看好的状元秀球员,他们被认为是重建球队扭转困境和命运的绝佳机会。至于2023年状元秀大热文班亚马被大罗说出来你不相信,足坛称得上中场大师的仅2人,皮尔洛不行罗纳尔多认为,纵观足坛历史,真正能称得上中场大师的只有2人,他们是里瓦尔多和齐达内,瓦刀的组织盘带射门都是天花板级别,单论提升球队层次的能力,同时期也没有人比齐达内更强,至于皮尔洛海港前主帅旧账被查出!吃回扣做假账,或面临牢狱之灾3月3日,中国足球协会主席陈戌源已经被带走2周有余,本以为相关部门会借此机会展开深入的调查,短时间内结束反腐扫黑行动!但从目前的情况来看,相关部门针对陈戌源刘奕陈永亮李铁等人的调查记者今年超级杯落户杭州黄龙体育中心,将于4月8日举行直播吧3月3日讯据记者徐毅报道,目前相关方面已经决定,2023年中国足球俱乐部赛事第一战超级杯赛,落户杭州黄龙体育中心,比赛将于4月8日举行。作为曾经的浙江队主场,黄龙体育中心在2中乙新军重庆铜梁龙发布新队徽,由蓝色变为红色ampampamp繁体字体现队名直播吧3月3日讯中乙新军重庆铜梁龙官方消息,俱乐部发布新队徽。上赛季,重庆铜梁龙征战中冠,最终以第二名的成绩升入中乙,重庆重新迎来职业俱乐部。俱乐部今天宣布发布新队徽,新队徽最大的
胎儿偏小一个月,怎么办?怀孕之后,准妈咪做产检,经常会遇到头部偏小或者偏大的情况,只要医生检查其他情况正常,一般是没有大问题的。但是,遇到产检胎头偏小,准妈咪还是会很担心,这种情况是如何产生的的?遗传有些孕妇喝什么汤补?孕妇在怀孕期间应该根据各个阶段的需求补充不一样的汤。一,孕早期补汤原则怀孕前三个月由于早孕反应,孕妈咪可以多喝一些清淡开胃的汤。比如乳鸽汤,不仅不油腻(没有肥肉),还可以补充营养。准妈妈如何调整日常行动姿势?孕妇在怀孕以后,特别随着肚子越来越大,在走路睡觉时,有些姿势会感觉到不舒服,但是又害怕改变之后对胎儿有影响?今天让我们来看看孕期改变姿势对胎儿的影响?一。妊娠早期的姿势此时在14周魔兽世界中有哪些违反逻辑的游戏设定?魔兽世界游戏设定相对一些脑洞比较大的游戏来说,魔兽世界中的游戏设定大部分都是符合现实世界的逻辑的,但是仍然有一些让人无语的设定,让人感觉到魔兽世界设计师的脑洞是那么的清奇。战士怒气生化危机2重制版有哪些不合逻辑的设定?虽然贵为经典,但生化系列一直就是走的爆米花路线,很多设定都经不起推敲。这次的重制版修改了原版的部分剧情和设定,使剧情更合理审美更符合现在的潮流,但原版中一些不合理的地方并没有明显减球迷热议中国女篮憾负日本,有人喊许利民下课,你认为对吗?中国女篮撼负日本队,实在是令国人不可接受,用郎平的话说,输谁也不能输给日本人!这是一种民族心。论实力,两个队不相上下,且身高我们佔绝对优势,但场上确打得很吃力,教练指挥当然有问题,逼迫中国男篮改革,周琦加盟NBL能成为第二个王治郅吗?不能,因为周琦想来辽宁队打比赛,篮协阻止,没比法只好走第二条路。暂时到澳洲打比赛,等到自由身以后,再转辽宁队,辽宁队是周琦的家,回家天经地义,谁也别想阻挡!支持周琦!姚明该退位!他世乒赛阵容浮出水面,国乒女队3人争2个名额,陈幸同还有机会吗?现在距世乒赛开赛还有一个多月的时间,女队中陈梦和王曼昱已经获得参赛权,这次乒超联赛再确定一个名额(从现在形势来看孙颖莎入围的可能性大,陈幸同的机会比孙颖莎小),此外的两个名额由乒协中国14亿人口大国今晚能战胜越南吗?22年世界杯还有希望吗?不关足协,不关李铁,10月8日凌晨这场中越之战,就是一场中国足球人自我救赎的战斗!这场球如果赢,后面出不出线事小,起码中国足球从业人员还可以继续好好生活下去。这场球如果输了,那么所老人怎么选择适合的助听器?助听器多少钱一个?很多人都会说年纪大了,配个便宜的助听器。如何配助听器也是要看听力损失的类型和严重程度的,如果只是传导性耳聋,那配个一般的便宜的都可以,但如果是混合性或者是高频差的患者,便宜的助听器分期免息买手机划算吗?想买个vivo手机?分期免息在购买预算上能减轻不少压力,不仅不用一次性付所有资金,而且分期后还不用利息,应该说是一个对消费者很友好的购买方式。双十一期间,vivo手机不仅推出了分期免息的方式其实也给了
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网