Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
΢ÐÅ Android ÊÓÆµ±àÂëÅÀ¹ýµÄÄÇЩ¿Ó
 
À´Ô´£º¼«¿ÍÍ·Ìõ ·¢²¼ÓÚ£º 2017-8-25
  3487  次浏览      29
 

Google Õë¶ÔÉãÏñÍ·ÒÔ¼°ÊÓÆµ±àÂëÏà¹ØµÄ API£¬¿ØÖÆÁ¦Ò»Ö±·Ç³£²î£¬µ¼Ö²»Í¬³§É̶ÔÕâÁ½¸ö API µÄʵÏÖÓв»ÉÙ²îÒ죬¶øÇÒ´Ó API µÄÉè¼ÆÀ´¿´£¬Ò»Ö±ÒÔÀ´ÓÅ»¯Ò²Ï൱ÓÐÏÞ£¬ÉõÖÁÓÐÈËÈÏΪÕâÊÇ¡°Android ÉÏ×îÄÑÓÃµÄ API Ö®Ò»¡±¡£

ÒÔ΢ÐÅΪÀý£¬ÔÚ Android Éè±¸Â¼ÖÆÒ»¸ö 540P µÄ MP4 Îļþ£¬´óÌåÉÏ×ñÑ­ÒÔÏÂÁ÷³Ì£º

ͼ1 Android ÊÓÆµÁ÷±àÂëÁ÷³Ìͼ

´ÓÉãÏñÍ·Êä³öµÄ YUV Ö¡¾­¹ýÔ¤´¦ÀíÖ®ºó£¬ËÍÈë±àÂëÆ÷£¬»ñµÃ±àÂëºÃµÄ H264 ÊÓÆµÁ÷¡£

ÉÏÃæÖ»ÊÇÕë¶ÔÊÓÆµÁ÷µÄ±àÂ룬ÁíÍ⻹ÐèÒª¶ÔÒôƵÁ÷µ¥¶ÀÂ¼ÖÆ£¬×îºóÔÙ½«ÊÓÆµÁ÷ºÍÒôƵÁ÷ºÏ³É×îÖÕÊÓÆµ¡£

ÕâÆªÎÄÕÂÖ÷Òª»á¶ÔÊÓÆµÁ÷µÄ±àÂëÖÐÁ½¸ö³£¼ûÎÊÌâ½øÐзÖÎö£º

1.ÊÓÆµ±àÂëÆ÷µÄÑ¡Ôñ£ºÓ²±à or Èí±à£¿

2.ÈçºÎ¶ÔÉãÏñÍ·Êä³öµÄ YUV Ö¡½øÐпìËÙÔ¤´¦Àí£º¾µÏñ¡¢Ëõ·Å¡¢Ðýת£¿

ÊÓÆµ±àÂëÆ÷µÄÑ¡Ôñ

¶ÔÓÚÂ¼ÖÆÊÓÆµµÄÐèÇ󣬲»ÉÙ App ¶¼ÐèÒª¶Ôÿһ֡Êý¾Ý½øÐе¥¶À´¦Àí£¬Òò´ËºÜÉÙ»áÖ±½ÓÓõ½ MediaRecorder À´Â¼È¡ÊÓÆµ£¬Ò»°ãÀ´Ëµ£¬»áÓÐÁ½¸öÑ¡Ôñ£º

1.MediaCodec

2.FFMpeg+x264/openh264

ÏÂÃæÎÒÃÇÖð¸ö½øÐнâÎö¡£

MediaCodec

MediaCodec ÊÇ API 16 Ö®ºó Google ÍÆ³öµÄÓÃÓÚÒôÊÓÆµ±à½âÂëµÄÒ»Ìׯ«µ×²ãµÄ API£¬¿ÉÒÔÖ±½ÓÀûÓÃÓ²¼þ¼ÓËÙ½øÐÐÊÓÆµµÄ±à½âÂë¡£µ÷ÓõÄʱºòÐèÒªÏȳõʼ»¯ MediaCodec ×÷ΪÊÓÆµµÄ±àÂëÆ÷£¬È»ºóÖ»ÐèÒª²»Í£´«ÈëԭʼµÄ YUV Êý¾Ý½øÈë±àÂëÆ÷¾Í¿ÉÒÔÖ±½ÓÊä³ö±àÂëºÃµÄ H.264 Á÷£¬Õû¸ö API Éè¼ÆÄ£ÐÍͬʱ°üº¬ÁËÊäÈë¶ËºÍÊä³ö¶ËµÄÁ½Ìõ¶ÓÁС£

Òò´Ë£¬×÷Ϊ±àÂëÆ÷£¬ÊäÈë¶Ë¶ÓÁдæ·ÅµÄÊÇԭʼ YUV Êý¾Ý£¬Êä³ö¶Ë¶ÓÁÐÊä³öµÄÊDZàÂëºÃµÄ H.264 Á÷£¬×÷Ϊ½âÂëÆ÷Ôò¶ÔÓ¦Ïà·´¡£ÔÚµ÷ÓõÄʱºò£¬MediaCodec ÌṩÁËͬ²½ºÍÒì²½Á½ÖÖµ÷Ó÷½Ê½£¬µ«ÊÇÒ첽ʹÓà Callback µÄ·½Ê½ÊÇÔÚ API 21 Ö®ºó²Å¼ÓÈëµÄ£¬ÒÔͬ²½µ÷ÓÃΪÀý£¬Ò»°ãÀ´Ëµµ÷Ó÷½Ê½´ó¸ÅÊÇÕâÑù£¨Õª×Ô¹Ù·½Àý×Ó£©£º

MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, ¡­);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferId >= 0) {
ByteBuffer inputBuffer = codec.getInputBuffer(¡­);
// fill inputBuffer with valid data
¡­
codec.queueInputBuffer(inputBufferId, ¡­);
}
int outputBufferId = codec.dequeueOutputBuffer(¡­);
if (outputBufferId >= 0) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is identical to outputFormat
// outputBuffer is ready to be processed or rendered.
¡­
codec.releaseOutputBuffer(outputBufferId, ¡­);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
outputFormat = codec.getOutputFormat(); // option B
}
}
codec.stop();
codec.release();

¼òµ¥½âÊÍһϣ¬Í¨¹ý getInputBuffers »ñÈ¡ÊäÈë¶ÓÁУ¬È»ºóµ÷Óà dequeueInputBuffer »ñÈ¡ÊäÈë¶ÓÁпÕÏÐÊý×éϱ꣬עÒâ dequeueOutputBuffer »áÓм¸¸öÌØÊâµÄ·µ»ØÖµ±íʾµ±Ç°±à½âÂë״̬µÄ±ä»¯£¬È»ºóÔÙͨ¹ý queueInputBuffer °Ñԭʼ YUV Êý¾ÝËÍÈë±àÂëÆ÷£¬¶øÔÚÊä³ö¶ÓÁжËͬÑùͨ¹ý getOutputBuffers ºÍ dequeueOutputBuffer »ñÈ¡Êä³öµÄ H.264 Á÷£¬´¦ÀíÍêÊä³öÊý¾ÝÖ®ºó£¬ÐèҪͨ¹ý releaseOutputBuffer °ÑÊä³ö buffer »¹¸øÏµÍ³£¬ÖØÐ·ŵ½Êä³ö¶ÓÁÐÖС£

¹ØÓÚ MediaCodec ¸ü¸´ÔÓµÄʹÓÃÀý×Ó£¬¿ÉÒÔ²ÎÕÕ CTS ²âÊÔÀïÃæµÄʹÓ÷½Ê½£ºEncodeDecodeTest.java¡£

´ÓÉÏÃæÀý×ÓÀ´¿´ MediaCodec µÄÈ·ÊǷdz£Ô­Ê¼µÄ API£¬ÓÉÓÚ MediaCodec µ×²ãÖ±½Óµ÷ÓÃÁËÊÖ»úƽ̨Ӳ¼þµÄ±à½âÂëÄÜÁ¦£¬ËùÒÔËٶȷdz£¿ì£¬µ«ÊÇÒòΪ Google ¶ÔÕû¸ö Android Ó²¼þÉú̬µÄÕÆ¿ØÁ¦·Ç³£Èõ£¬ËùÒÔÕâ¸ö API ÓкܶàÎÊÌ⣺

ÑÕÉ«¸ñʽÎÊÌâ

MediaCodec ÔÚ³õʼ»¯µÄʱºò£¬configure ¹ý³ÌÖÐÐèÒª´«ÈëÒ»¸ö MediaFormat ¶ÔÏ󣬵±×÷Ϊ±àÂëÆ÷ʹÓõÄʱºò£¬ÎÒÃÇÒ»°ãÐèÒªÔÚ MediaFormat ÖÐÖ¸¶¨ÊÓÆµµÄ¿í¸ß¡¢Ö¡ÂÊ¡¢ÂëÂÊ¡¢I Ö¡¼ä¸ôµÈ»ù±¾ÐÅÏ¢¡£³ý´ËÖ®Í⣬»¹ÓÐÒ»¸öÖØÒªµÄÐÅÏ¢¾ÍÊÇ£¬Ö¸¶¨±àÂëÆ÷½ÓÊÜµÄ YUV Ö¡µÄÑÕÉ«¸ñʽ£¬ÕâÊÇÓÉÓÚ YUV ¸ù¾ÝÆä²ÉÑù±ÈÀý£¬UV ·ÖÁ¿µÄÅÅÁÐ˳ÐòÓкܶàÖÖ²»Í¬µÄÑÕÉ«¸ñʽ£¬¶ø¶ÔÓÚ Android µÄÉãÏñÍ·ÔÚ onPreviewFrame Êä³öµÄ YUV Ö¡¸ñʽ£¬Ã»ÓÐÅäÖÃÈκβÎÊýµÄÇé¿öÏ£¬»ù±¾É϶¼ÊÇ NV21 ¸ñʽ£¬µ« Google ¶Ô MediaCodec µÄ API ÔÚÉè¼ÆºÍ¹æ·¶µÄʱºò£¬ÏԵúܲ»ºñµÀ£¬¹ýÓÚÌù½ü Android µÄ HAL ²ãÁË£¬µ¼ÖÂÁË NV21 ¸ñʽ²¢²»ÊÇËùÓлúÆ÷µÄ MediaCodec ¶¼Ö§³ÖÕâÖÖ¸ñʽ×÷Ϊ±àÂëÆ÷µÄÊäÈë¸ñʽ¡£ Òò´Ë£¬ÔÚ³õʼ»¯ MediaCodec µÄʱºò£¬ÎÒÃÇÐèҪͨ¹ý codecInfo.getCapabilitiesForType À´²éѯ»úÆ÷É쵀 MediaCodec ʵÏÖ¾ßÌåÖ§³ÖÄÄЩ YUV ¸ñʽ×÷ΪÊäÈë¸ñʽ¡£Ò»°ãÀ´Ëµ£¬ÆðÂëÔÚ 4.4+ µÄϵͳÉÏ£¬ÕâÁ½ÖÖ¸ñʽÔڴ󲿷ֻúÆ÷É϶¼ÓÐÖ§³Ö£º

MediaCodecInfo.CodecCapabilities.COLOR_

FormatYUV420Planar
MediaCodecInfo.CodecCapabilities.COLOR_

FormatYUV420SemiPlanar

Á½ÖÖ¸ñʽ·Ö±ðÊÇ YUV420P ºÍ NV21£¬Èç¹û»úÆ÷ÉÏÖ»Ö§³Ö YUV420P ¸ñʽ£¬ÔòÐèÒªÏȽ«ÉãÏñÍ·Êä³öµÄ NV21 ¸ñʽÏÈת»»³É YUV420P£¬²ÅÄÜËÍÈë±àÂëÆ÷½øÐбàÂ룬·ñÔò×îÖÕ³öÀ´µÄÊÓÆµ¾Í»á»¨ÆÁ£¬»òÕßÑÕÉ«³öÏÖ´íÂÒ¡£

Õâ¸öËãÊÇÒ»¸ö²»´ó²»Ð¡µÄ¿Ó£¬»ù±¾ÉÏÓà MediaCodec ½øÐÐÊÓÆµ±àÂë¶¼»áÓöÉÏÕâ¸öÎÊÌâ¡£

±àÂëÆ÷Ö§³ÖÌØÐÔÏ൱ÓÐÏÞ

Èç¹ûʹÓà MediaCodec À´±àÂë H.264 ÊÓÆµÁ÷£¬¶ÔÓÚ H.264 ¸ñʽÀ´Ëµ£¬»áÓÐһЩÕë¶ÔѹËõÂÊÒÔ¼°ÂëÂÊÏà¹ØµÄÊÓÆµÖÊÁ¿ÉèÖ㬵äÐ͵ÄÖîÈç Profile£¨baseline, main, hight£©¡¢Profile Level¡¢Bitrate mode£¨CBR¡¢CQ¡¢VBR£©£¬ºÏÀíÅäÖÃÕâЩ²ÎÊý¿ÉÒÔÈÃÎÒÃÇÔÚͬµÈµÄÂëÂÊÏ£¬»ñµÃ¸ü¸ßµÄѹËõÂÊ£¬´Ó¶øÌáÉýÊÓÆµµÄÖÊÁ¿£¬Android Ò²ÌṩÁ˶ÔÓ¦µÄ API ½øÐÐÉèÖ㬿ÉÒÔÉèÖõ½ MediaFormat ÖУº

MediaFormat.KEY_BITRATE_MODE
MediaFormat.KEY_PROFILE
MediaFormat.KEY_LEVEL

µ«ÎÊÌâÊÇ£¬¶ÔÓÚ Profile¡¢Level¡¢Bitrate mode ÕâЩÉèÖã¬Ôڴ󲿷ÖÊÖ»úÉ϶¼ÊDz»Ö§³ÖµÄ£¬¼´Ê¹ÊÇÉèÖÃÁË×îÖÕÒ²²»»áÉúЧ£¬ÀýÈçÉèÖÃÁË Profile Ϊ high£¬×îºó³öÀ´µÄÊÓÆµÒÀÈ»»¹»áÊÇ Baseline¡£

Õâ¸öÎÊÌ⣬ÔÚ 7.0 ÒÔϵĻúÆ÷¼¸ºõÊDZØÏֵ쬯äÖÐÒ»¸ö¿ÉÄܵÄÔ­ÒòÊÇ£¬Android ÔÚÔ´Âë²ã¼¶ hardcode ÁË Profile µÄµÄÉèÖãº

// XXX
if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
ALOGW("Use baseline profile instead of %d for AVC recording",
h264type.eProfile);
h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
}

Android Ö±µ½ 7.0 Ö®ºó²ÅÈ¡ÏûÁËÕâ¶ÎµØ·½µÄ Hardcode¡£

if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
....
} else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
.....
}

Õâ¸öÎÊÌâ¿ÉÒÔ˵¼ä½Óµ¼ÖÂÁË MediaCodec ±àÂë³öÀ´µÄÊÓÆµÖÊÁ¿Æ«µÍ£¬Í¬µÈÂëÂÊÏ£¬ÄÑÒÔ»ñµÃ¸úÈí±àÂëÉõÖÁ iOS ÄÇÑùµÄÊÓÆµÖÊÁ¿¡£

16 λ¶ÔÆëÒªÇó

Ç°ÃæËµµ½£¬MediaCodec Õâ¸ö API ÔÚÉè¼ÆµÄʱºò£¬¹ýÓÚÌù½ü HAL ²ã£¬ÕâÔںܶà SoC µÄʵÏÖÉÏ£¬ÊÇÖ±½Ó°Ñ´«Èë MediaCodec µÄ buffer£¬ÔÚ²»¾­¹ýÈκÎǰÖô¦ÀíµÄÇé¿öϾÍÖ±½ÓËÍÈëÁË Soc ÖС£¶øÔÚ±àÂë H264 ÊÓÆµÁ÷µÄʱºò£¬ÓÉÓÚ H264 µÄ±àÂë¿é´óСһ°ãÊÇ 16x16£¬ÓÚÊÇÔÚÒ»¿ªÊ¼ÉèÖÃÊÓÆµ¿í¸ßµÄʱºò£¬Èç¹ûÉèÖÃÁËÒ»¸öûÓÐ¶ÔÆë 16 µÄ´óС£¬ÀýÈç 960x540£¬ÔÚijЩ CPU ÉÏ£¬×îÖÕ±àÂë³öÀ´µÄÊÓÆµ¾Í»áÖ±½Ó»¨ÆÁ¡£

ºÜÃ÷ÏÔÕ⻹ÊÇÒòΪ³§ÉÌÔÚʵÏÖÕâ¸ö API µÄʱºò£¬¶Ô´«ÈëµÄÊý¾ÝȱÉÙУÑéÒÔ¼°Ç°Öô¦Àíµ¼Öµġ£Ä¿Ç°À´¿´£¬»ªÎª¡¢ÈýÐÇµÄ SoC ³öÏÖÕâ¸öÎÊÌâ»á±È½ÏƵ·±£¬ÆäËû³§É̵ÄһЩÔçÆÚ Soc Ò²ÓÐÕâÖÖÎÊÌ⣬һ°ãÀ´Ëµ½â¾ö·½·¨»¹ÊÇÔÚÉèÖÃÊÓÆµ¿í¸ßµÄʱºò£¬Í³Ò»ÉèÖÃ³É¶ÔÆë 16 λ¾ÍºÃÁË¡£

FFMpeg+x264/openh264

³ýÁËʹÓà MediaCodec ½øÐбàÂëÖ®Í⣬ÁíÍâÒ»ÖֱȽÏÁ÷Ðеķ½°¸¾ÍÊÇʹÓà FFmpeg + x264/OpenH264 ½øÐÐÈí±àÂ룬FFmpeg ÊÊÓÃÓÚһЩÊÓÆµÖ¡µÄÔ¤´¦Àí¡£ÕâÀïÖ÷ÒªÊÇʹÓà x264/OpenH264 ×÷ΪÊÓÆµµÄ±àÂëÆ÷¡£

x264 »ù±¾Éϱ»ÈÏΪÊǵ±½ñÊÐÃæÉÏ×î¿ìµÄÉÌÓÃÊÓÆµ±àÂëÆ÷£¬¶øÇÒ»ù±¾ÉÏËùÓÐ H264 µÄÌØÐÔ¶¼Ö§³Ö£¬Í¨¹ýºÏÀíÅäÖø÷ÖÖ²ÎÊý»¹ÊÇÄܹ»µÃµ½½ÏºÃµÄѹËõÂʺͱàÂëËٶȵģ¬ÏÞÓÚÆª·ù£¬ÕâÀï²»ÔÙ²ûÊö H.264 µÄ²ÎÊýÅäÖá£

OpenH264 ÔòÊÇÓÉ˼¿Æ¿ªÔ´µÄÁíÍâÒ»¸ö H264 ±àÂëÆ÷£¬ÏîÄ¿ÔÚ 2013 Ä꿪Դ£¬¶Ô±ÈÆð x264 À´ËµÂÔÏÔÄêÇᣬ²»¹ýÓÉÓÚ˼¿ÆÖ§¸¶ÂòÁË H.264 µÄÄê¶ÈרÀû·Ñ£¬ËùÒÔ¶ÔÓÚÍⲿÓû§À´Ëµ£¬Ï൱ÓÚ¿ÉÒÔÖ±½ÓÃâ·ÑʹÓÃÁË¡£ÁíÍ⣬firefox Ö±½ÓÄÚÖÃÁË OpenH264£¬×÷ΪÆäÔÚ WebRTC ÖеÄÊÓÆµ±à½âÂëÆ÷ʹÓá£

µ«¶Ô±ÈÆð x264£¬OpenH264 ÔÚ H264 ¸ß¼¶ÌØÐÔµÄÖ§³Ö±È½Ï²î£º

Profile Ö»Ö§³Öµ½ baseline£¬level 5.2£»

¶àÏ̱߳àÂëÖ»Ö§³Ö slice based£¬²»Ö§³Ö frame based µÄ¶àÏ̱߳àÂë¡£

´Ó±àÂëЧÂÊÉÏÀ´¿´£¬OpenH264 µÄËÙ¶ÈÒ²²¢²»»á±È x264 ¿ì£¬²»¹ýÆä×î´óµÄºÃ´¦£¬»¹ÊÇÄܹ»Ö±½ÓÃâ·ÑʹÓá£

ÈíÓ²±à¶Ô±È

´ÓÉÏÃæµÄ·ÖÎöÀ´¿´£¬Ó²±àµÄºÃ´¦Ö÷ÒªÔÚÓÚËٶȿ죬¶øÇÒϵͳ×Ô´ø£¬²»ÐèÒªÒýÈëÍⲿµÄ¿â£¬µ«ÊÇÌØÐÔÖ§³ÖÓÐÏÞ£¬¶øÇÒÓ²±àµÄѹËõÂÊÒ»°ãÆ«µÍ¡£¶ÔÓÚÈí±àÂëÀ´Ëµ£¬ËäÈ»ËٶȽÏÂý£¬µ«ÊÇѹËõÂʱȽϸߣ¬¶øÇÒÖ§³ÖµÄ H264 ÌØÐÔÒ²»á±ÈÓ²±àÂë¶àºÜ¶à£¬Ïà¶ÔÀ´Ëµ±È½Ï¿É¿Ø¡£¾Í¿ÉÓÃÐÔ¶øÑÔ£¬ÔÚ 4.4+µÄϵͳÉÏ£¬MediaCodec µÄ¿ÉÓÃÐÔÊÇÄܹ»»ù±¾±£Ö¤µÄ£¬µ«ÊDz»Í¬µÈ¼¶»úÆ÷µÄ±àÂëÆ÷ÄÜÁ¦»áÓв»ÉÙ²î±ð£¬½¨Òé¿ÉÒÔ¸ù¾Ý»úÆ÷µÄÅäÖã¬Ñ¡Ôñ²»Í¬µÄ±àÂëÆ÷ÅäÖá£

YUV Ö¡µÄÔ¤´¦Àí

¸ù¾Ý×ʼ¸ø³öµÄÁ÷³Ì£¬ÔÚËÍÈë±àÂëÆ÷֮ǰ£¬ÎÒÃÇÐèÒªÏȶÔÉãÏñÍ·Êä³öµÄ YUV Ö¡½øÐÐһЩǰÖô¦Àí¡£

Ëõ·Å

Èç¹ûÉèÖÃÁË Camera µÄÔ¤ÀÀ´óСΪ 1080P£¬ÔÚ onPreviewFrame ÖÐÊä³öµÄ YUV Ö¡Ö±½Ó¾ÍÊÇ 1920x1080 µÄ´óС£¬Èç¹ûÐèÒª±àÂë¸úÕâ¸ö´óС²»Ò»ÑùµÄÊÓÆµ£¬ÎÒÃǾÍÐèÒªÔÚÂ¼ÖÆµÄ¹ý³ÌÖУ¬ÊµÊ±µÄ¶Ô YUV Ö¡½øÐÐËõ·Å¡£

ÒÔ΢ÐÅΪÀý£¬ÉãÏñÍ·Ô¤ÀÀ 1080P µÄÊý¾Ý£¬ÐèÒª±àÂë 960x540 ´óСµÄÊÓÆµ¡£

×îΪ³£¼ûµÄ×ö·¨ÊÇʹÓà FFmpeg µÄ swsscale º¯Êý½øÐÐÖ±½ÓËõ·Å£¬Ð§¹û/ÐÔÄܱȽϺõÄÒ»°ãÊÇÑ¡Ôñ SWSFAST_BILINEAR Ëã·¨£º

mScaleYuvCtxPtr = sws_getContext(
srcWidth,
srcHeight,
AV_PIX_FMT_NV21,
dstWidth,
dstHeight,
AV_PIX_FMT_NV21,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
sws_scale(mScaleYuvCtxPtr,
(const uint8_t* const *) srcAvPicture->data,
srcAvPicture->linesize, 0, srcHeight,
dstAvPicture->data, dstAvPicture->linesize);

ÔÚ Nexus 6P ÉÏ£¬Ö±½ÓʹÓà FFmpeg À´½øÐÐËõ·ÅµÄʱ¼ä»ù±¾É϶¼ÐèÒª 40ms+£¬¶ÔÓÚÎÒÃÇÐèÒªÂ¼ÖÆ 30fps µÄÀ´Ëµ£¬Ã¿Ö¡´¦Àíʱ¼ä×î¶à¾Í 30ms£¬Èç¹û¹âÊÇËõ·Å¾ÍÏûºÄÁËÈç´Ë¶àµÄʱ¼ä£¬»ù±¾ÉÏÂ¼ÖÆ³öÀ´µÄÊÓÆµÖ»ÄÜÔÚ 15fps ÉÏÏÂÁË¡£

ºÜÃ÷ÏÔ£¬Ö±½ÓʹÓà FFmpeg ½øÐÐËõ·ÅʵÔÚÌ«ÂýÁË£¬²»µÃ²»Ëµ swsscale ÔÚ FFmpeg ÀïÃæ²»ÊÊÓ᣾­¶Ô±ÈÁ˼¸ÖÖÒµ½ç³£ÓõÄËã·¨Ö®ºó£¬ÎÒÃÇ×îºó¿¼ÂÇʹÓÿìËÙËõ·ÅµÄËã·¨£¬Èçͼ 3 Ëùʾ¡£

ÎÒÃÇÑ¡ÔñÒ»ÖÖ½Ð×ö¾Ö²¿¾ùÖµµÄËã·¨£¬Ç°ºóÁ½ÐÐËĸöÁÙ½üµãËã³ö×îÖÕͼƬµÄËĸöÏñËØµã£¬¶ÔÓÚԴͼƬµÄÿÐÐÏñËØ£¬ÎÒÃÇ¿ÉÒÔʹÓà Neon Ö±½ÓʵÏÖ£¬ÒÔËõ·Å Y ·ÖÁ¿ÎªÀý£º

const uint8* src_next = src_ptr + src_stride;
asm volatile (
"1: \n"
"vld4.8 {d0, d1, d2, d3}, [%0]! \n"
"vld4.8 {d4, d5, d6, d7}, [%1]! \n"
"subs %3, %3, #16 \n" // 16 processed per loop
"vrhadd.u8 d0, d0, d1 \n"
"vrhadd.u8 d4, d4, d5 \n"
"vrhadd.u8 d0, d0, d4 \n"
"vrhadd.u8 d2, d2, d3 \n"
"vrhadd.u8 d6, d6, d7 \n"
"vrhadd.u8 d2, d2, d6 \n"
"vst2.8 {d0, d2}, [%2]! \n" // store odd pixels
"bgt 1b \n"
: "+r"(src_ptr), // %0
"+r"(src_next), // %1
"+r"(dst), // %2
"+r"(dst_width) // %3
:
: "q0", "q1", "q2", "q3" // Clobber List
);

ÉÏÃæÊ¹ÓÃµÄ Neon Ö¸Áîÿ´ÎÖ»ÄܶÁÈ¡ºÍ´æ´¢ 8 »òÕß 16 λµÄÊý¾Ý£¬¶ÔÓÚ¶à³öÀ´µÄÊý¾Ý£¬Ö»ÐèÒªÓÃͬÑùµÄËã·¨¸Ä³ÉÓà C ÓïÑÔʵÏÖ¼´¿É¡£

ÔÚʹÓÃÉÏÊöµÄËã·¨ÓÅ»¯Ö®ºó£¬½øÐÐÿ֡Ëõ·Å£¬ÔÚ Nexus 6P ÉÏ£¬Ö»ÐèÒª²»µ½ 5ms ¾ÍÄÜÍê³ÉÁË£¬¶ø¶ÔÓÚËõ·ÅÖÊÁ¿À´Ëµ£¬FFmpeg µÄ SWSFASTBILINEAR Ëã·¨ºÍÉÏÊöËã·¨Ëõ·Å³öÀ´µÄͼƬ½øÐжԱȣ¬·åÖµÐÅÔë±È£¨psnr£©Ôڴ󲿷ֳ¡¾°Ï´ó¸ÅÔÚ 38-40 ×óÓÒ£¬ÖÊÁ¿Ò²×ã¹»ºÃ¡£

Ðýת

ÔÚ Android »úÆ÷ÉÏ£¬ÓÉÓÚÉãÏñÍ·°²×°½Ç¶È²»Í¬£¬onPreviewFrame ³öÀ´µÄ YUV Ö¡Ò»°ã¶¼ÊÇÐýתÁË 90 ¶È»òÕß 270 ¶È£¬Èç¹û×îÖÕÊÓÆµÊÇÒªÊúÅĵģ¬ÄÇÒ»°ãÀ´ËµÐèÒª°Ñ YUV Ö¡½øÐÐÐýת¡£

¶ÔÓÚÐýתµÄËã·¨£¬Èç¹ûÊÇ´¿ C ʵÏֵĴúÂ룬һ°ãÀ´ËµÊǸö O£¨n2 £©¸´ÔӶȵÄËã·¨£¬Èç¹ûÊÇÐýת 960x540 µÄ YUV Ö¡Êý¾Ý£¬ÔÚ Nexus 6P ÉÏ£¬Ã¿Ö¡ÐýתҲÐèÒª 30ms+£¬ÕâÏÔȻҲÊDz»ÄܽÓÊܵġ£

ÔÚÕâÀïÎÒÃÇ»»¸ö˼·£¬Äܲ»Äܲ»¶Ô YUV Ö¡½øÐÐÐýת£¿ÏÔµ±È»ÊÇ¿ÉÒԵġ£

ÊÂʵÉÏÔÚ MP4 Îļþ¸ñʽµÄÍ·²¿£¬ÎÒÃÇ¿ÉÒÔÖ¸¶¨Ò»¸öÐýת¾ØÕ󣬾ßÌåÀ´ËµÊÇÔÚ moov.trak.tkhd box ÀïÃæÖ¸¶¨£¬ÊÓÆµ²¥·ÅÆ÷ÔÚ²¥·ÅÊÓÆµµÄʱºò£¬»á¶ÁÈ¡ÕâÀïµÄ¾ØÕóÐÅÏ¢£¬´Ó¶ø¾ö¶¨ÊÓÆµ±¾ÉíµÄÐýת½Ç¶È¡¢Î»ÒÆ¡¢Ëõ·ÅµÈ£¬¾ßÌå¿ÉÒԲο¼Æ»¹ûµÄÎĵµ¡£

ͨ¹ý FFmpeg£¬ÎÒÃÇ¿ÉÒÔºÜÇáËɵĸøºÏ³ÉÖ®ºóµÄ mp4 Îļþ´òÉÏÕâ¸öÐýת½Ç¶È£º

char rotateStr[1024];
sprintf(rotateStr, "%d", rotate);
av_dict_set(&out_stream->metadata, "rotate", rotateStr, 0);

ÓÚÊÇ¿ÉÒÔÔÚÂ¼ÖÆµÄʱºòÊ¡ÏÂÒ»´ó±ÊÐýתµÄ¿ªÏú¡£

¾µÏñ

ÔÚʹÓÃǰÖÃÉãÏñÍ·ÅÄÉãµÄʱºò£¬Èç¹û²»¶Ô YUV Ö¡½øÐд¦Àí£¬ÄÇôֱ½ÓÅijöÀ´µÄÊÓÆµÊǻ᾵Ïñ·­×ªµÄ£¬ÕâÀïÔ­Àí¾Í¸úÕÕ¾µ×ÓÒ»Ñù£¬´ÓǰÖÃÉãÏñÍ··½ÏòÄóöÀ´µÄ YUV Ö¡¸ÕºÃÊÇ·´µÄ£¬µ«ÓÐЩʱºòÅijöÀ´µÄ¾µÏñÊÓÆµ¿ÉÄܲ»ºÏÎÒÃǵÄÐèÇó£¬Òò´ËÕâ¸öʱºòÎÒÃǾÍÐèÒª¶Ô YUV Ö¡½øÐоµÏñ·­×ª¡£

µ«ÓÉÓÚÉãÏñÍ·°²×°½Ç¶ÈÒ»°ãÊÇ 90 ¶È»òÕß 270 ¶È£¬ËùÒÔʵ¼ÊÉÏÔ­ÉúµÄ YUV Ö¡ÊÇˮƽ·­×ª¹ýÀ´µÄ£¬Òò´Ë×ö¾µÏñ·­×ªµÄʱºò£¬Ö»ÐèÒª¸ÕºÃÒÔÖмäΪÖÐÖᣬ·Ö±ðÉÏϽ»»»Ã¿ÐÐÊý¾Ý¼´¿É£¬×¢Òâ Y ¸ú UV Òª·Ö¿ª´¦Àí£¬ÕâÖÖËã·¨Óà Neon ʵÏÖÏ൱¼òµ¥£º

asm volatile (
"1: \n"
"vld4.8 {d0, d1, d2, d3}, [%2]! \n" // load 32 from src
"vld4.8 {d4, d5, d6, d7}, [%3]! \n" // load 32 from dst
"subs %4, %4, #32 \n" // 32 processed per loop
"vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 32 to dst
"vst4.8 {d4, d5, d6, d7}, [%0]! \n" // store 32 to src
"bgt 1b \n"
: "+r"(src), // %0
"+r"(dst), // %1
"+r"(srcdata), // %2
"+r"(dstdata), // %3
"+r"(count) // %4 // Output registers
: // Input registers
: "cc", "memory", "q0", "q1", "q2", "q3" // Clobber List
);

ͬÑù£¬Ê£ÓàµÄÊý¾ÝÓô¿ C ´úÂëʵÏ־ͺÃÁË£¬ ÔÚ Nexus 6P ÉÏ£¬ÕâÖÖ¾µÏñ·­×ªÒ»Ö¡ 1080x1920 YUV Êý¾Ý´ó¸ÅÖ»Òª²»µ½ 5ms¡£

ÔÚ±àÂëºÃ H.264 ÊÓÆµÁ÷Ö®ºó£¬×îÖÕ´¦Àí¾ÍÊǰÑÒôƵÁ÷¸úÊÓÆµÁ÷ºÏÁ÷È»ºó°ü×°µ½ mp4 Îļþ£¬Õⲿ·ÖÎÒÃÇ¿ÉÒÔͨ¹ýϵͳµÄ MediaMuxer¡¢mp4v2£¬»òÕß FFmpeg À´ÊµÏÖ£¬Õⲿ·Ö±È½Ï¼òµ¥£¬ÔÚÕâÀï¾Í²»ÔÙ²ûÊöÁË¡£

   
3487 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì