androidstagefright
Ⅰ opencore和stagefrighten的區別
OpenCore組織codec等等些組建統介面MediaPlayer調用OpenCore東西用太關層codec體解釋OpenCore較新Android已經用代替Stagefright比OpenCore簡潔 般"框架"都理解真干「東西」負責些具體干「東西」組織起層模塊能完些通用功能讓更/便調用具體干「東西」沒"框架"實現同功
Ⅱ android手機有默認解碼器嗎
實際上系統中存在的解碼器可以很多,但能夠被應用使用的解碼器是根據配置來的,在/system/etc/media_codecc.xml中配置。這個文件一般由硬體或者系統的生產廠家在build整個系統的時候提供,一般是保存在代碼的device/[company]/[codename]目錄下的,例如device/samsung/tuna/media_codecs.xml。這個文件配置了系統中有哪些可用的codec以及,這些codec對應的媒體文件類型。在這個文件裡面,系統裡面提供的軟硬codec都需要被列出來。
也就是說,如果系統裡面實際上包含了某個codec,但是並沒有被配置在這個文件里,那麼應用程序也無法使用到!
在這里配置文件裡面,如果出現多個codec對應同樣類型的媒體格式的時候,這些codec都會被保留起來。當系統使用的時候,將後選擇第一個匹配的codec。除非是指明了要軟解碼還是硬解碼,但是Android的framework層為上層提供服務的AwesomePlayer中在處理音頻和視頻的時候,對到底是選擇軟解還是硬解的參數沒有設置。所以雖然底層是支持選擇的,但是對於上層使用MediaPlayer的Java程序來說,還是只能接受默認的codec選取規則。
但是Android提供的命令行程序/system/bin/stagefright在播放音頻文件的時候,倒是可以根據參數來選擇到底使用軟解碼還是硬解碼,但是該工具只支持播放音頻,不支持播放視頻。
一般來說,如果系統裡面有對應媒體的硬體解碼器的話,系統開發人員應該是會配置在media_codecs.xml中,所以大多數情況下,如果有硬體解碼器,那麼我們總是會使用到硬體解碼器。極少數情況下,硬體解碼器存在,但不配置,我猜測只可能是這個硬解碼器還有bug,暫時還不適合發布。
Ⅲ stagefright是什麼高危漏洞
這個關鍵漏洞位於Android的名為「Stagefright」的核心庫中,這是一個原生的媒體播放庫,供Android系統用來處理、記錄和播放多媒體文件。
Stagefright是一個真正可以主動利用的安全漏洞,也就是說,只要黑客知道你的電話號碼,然後發送一條惡意MMS給你,就能侵入 Android 手機,取得控制權,根本無需受害者任何交互。更可怕的是還能神不知鬼不覺,侵入系統後就刪除訊息,不會讓主人察覺。
不知道電話號碼 照樣黑你
但是,據最近的一項研究聲稱,現在根本不需要知道受害者的行動電話號碼,照樣可以感染他們的設備。
在此前獲悉的攻擊情形中,攻擊者只能針對已知聯系號碼的手機來發動Stagefright攻擊。這意味著攻擊者需要提前知道目標設備的電話號碼。
這樣的攻擊情形實際上不太可能發生,因為如果攻擊者想要進行大規模的感染,即使他們有大量資金來發送國內和國際MMS的話,也得知道巨量目標設備的電話號碼才行。
觸發Stagefright漏洞的新方法
目前,趨勢科技的安全研究人員已經發現了兩種新的攻擊方案,無需發送惡意的彩信就可以直接觸發Stagefright漏洞:
通過Android應用觸發漏洞
為訪問互聯網網頁的攻擊目標精心構造HTML漏洞利用
與之前的攻擊手段相比,這兩種新型的Stagefright攻擊向量帶來了更加嚴重的安全威脅,因為攻擊者可以利用該BUG遠程進行下列活動:
在不知道受害者的電話號碼且不費一分錢的情況下,就能黑掉數以百萬計的Android設備。
切取海量數據。
利用黑掉的Android設備打造僵屍網路,等等。
「精心構造的特殊MP4文件,能夠破壞或利用媒體伺服器的堆」,研究人員解釋道,這就是利用應用程序觸發Stagefright攻擊的方法。
Ⅳ 【Android】stagefright utils media這些庫都在哪
手機root之後,可以在/system/libs/下找到所有的so,NDK里沒有的。或者你也可以下載源碼,編譯之後可以找到相應的so。LOCAL_LDLIBS += -L $(path-to-system-libs) -lcutils。
Ⅳ 安卓stagefright檢測怎麼用
1、 StageFright介紹
Android froyo版本多媒體引擎做了變動,新添加了stagefright框架,並且默認情況android選擇stagefright,並沒有完全拋棄opencore,主要是做了一個OMX層,僅僅是對 opencore的omx-component部分做了引用。stagefright是在MediaPlayerService這一層加入的,和opencore是並列的。Stagefright在 Android中是以shared library的形式存在(libstagefright.so),其中的mole -- AwesomePlayer可用來播放video/audio。 AwesomePlayer提供許多API,可以讓上層的應用程序(Java/JNI)來調用。
2、 StageFright數據流封裝
2.1》由數據源DataSource生成MediaExtractor。通過MediaExtractor::Create(dataSource)來實現。Create方法通過兩步來生成相應的 MediaExtractor(MediaExtractor.cpp):
通過dataSource->sniff來探測數據類型
生成相應的Extractor:
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
|| !strcasecmp(mime, "audio/mp4")) {
return new MPEG4Extractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
return new MP3Extractor(source, meta);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
return new AMRExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
return new WAVExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {
return new OggExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {
return new MatroskaExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
return new MPEG2TSExtractor(source);
}
2.2》把音視頻軌道分離,生成mVideoTrack和mAudioTrack兩個MediaSource。代碼如下(AwesomePlayer.cpp):
if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
setVideoSource(extractor->getTrack(i));
haveVideo = true;
} else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
setAudioSource(extractor->getTrack(i));
haveAudio = true;
}
2.3》得到的這兩個MediaSource,只具有parser功能,沒有decode功能。還需要對這兩個MediaSource做進一步的包裝,獲取了兩個MediaSource(具有parse和decode功能):
mVideoSource = OMXCodec::Create(
mClient.interface(), mVideoTrack->getFormat(),
false, // createEncoder
mVideoTrack,
NULL, flags);
mAudioSource = OMXCodec::Create(
mClient.interface(), mAudioTrack->getFormat(),
false, // createEncoder
mAudioTrack);
當調用MediaSource.start()方法後,它的內部就會開始從數據源獲取數據並解析,等到緩沖區滿後便停止。在AwesomePlayer里就可以調用MediaSource的read方法讀取解碼後的數據。
對於mVideoSource來說,讀取的數據:mVideoSource->read(&mVideoBuffer, &options)交給顯示模塊進行渲染,mVideoRenderer->render(mVideoBuffer);
對mAudioSource來說,用mAudioPlayer對mAudioSource進行封裝,然後由mAudioPlayer負責讀取數據和播放控制。
3、 StageFright的Decode
經過「數據流的封裝」得到的兩個MediaSource,其實是兩個OMXCodec。AwesomePlayer和mAudioPlayer都是從MediaSource中得到數據進行播放。AwesomePlayer得到的是最終需要渲染的原始視頻數據,而mAudioPlayer讀取的是最終需要播放的原始音頻數據。也就是說,從OMXCodec中讀到的數據已經是原始數據了。
OMXCodec是怎麼把數據源經過parse、decode兩步以後轉化成原始數據的。從OMXCodec::Create這個構造方法開始,它的參數:
IOMX &omx指的是一個OMXNodeInstance對象的實例。
MetaData &meta這個參數由MediaSource.getFormat獲取得到。這個對象的主要成員就是一個KeyedVector<uint32_t, typed_data> mItems,裡面存放了一些代表MediaSource格式信息的名值對。
bool createEncoder指明這個OMXCodec是編碼還是解碼。
MediaSource &source是一個MediaExtractor。
char *matchComponentName指定一種Codec用於生成這個OMXCodec。
先使用findMatchingCodecs尋找對應的Codec,找到以後為當前IOMX分配節點並注冊事件監聽器:omx->allocateNode(componentName, observer, &node)。最後,把IOMX封裝進一個OMXCodec:
sp<OMXCodec> codec = new OMXCodec(
omx, node, quirks,
createEncoder, mime, componentName,
source);
這樣就得到了OMXCodec。
AwesomePlayer中得到這個OMXCodec後,首先調用mVideoSource->start()進行初始化。 OMXCodec初始化主要是做兩件事:
向OpenMAX發送開始命令。mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle)
調用allocateBuffers()分配兩個緩沖區,存放在Vector<BufferInfo> mPortBuffers[2]中,分別用於輸入和輸出。
AwesomePlayer開始播放後,通過mVideoSource->read(&mVideoBuffer, &options)讀取數據。mVideoSource->read(&mVideoBuffer, &options)具體是調用OMXCodec.read來讀取數據。而OMXCodec.read主要分兩步來實現數據的讀取:
通過調用drainInputBuffers()對mPortBuffers[kPortIndexInput]進行填充,這一步完成 parse。由OpenMAX從數據源把demux後的數據讀取到輸入緩沖區,作為OpenMAX的輸入。
通過fillOutputBuffers()對mPortBuffers[kPortIndexOutput]進行填充,這一步完成 decode。由OpenMAX對輸入緩沖區中的數據進行解碼,然後把解碼後可以顯示的視頻數據輸出到輸出緩沖區。
AwesomePlayer通過mVideoRenderer->render(mVideoBuffer)對經過parse和decode 處理的數據進行渲染。一個mVideoRenderer其實就是一個包裝了IOMXRenderer的AwesomeRemoteRenderer:
mVideoRenderer = new AwesomeRemoteRenderer(
mClient.interface()->createRenderer(
mISurface, component,
(OMX_COLOR_FORMATTYPE)format,
decodedWidth, decodedHeight,
mVideoWidth, mVideoHeight,
rotationDegrees));
4、 StageFright處理流程
Audioplayer 為AwesomePlayer的成員,audioplayer通過callback來驅動數據的獲取,awesomeplayer則是通過 videoevent來驅動。二者有個共性,就是數據的獲取都抽象成mSource->Read()來完成,且read內部把parser和dec 綁在一起。Stagefright AV同步部分,audio完全是callback驅動數據流,video部分在onVideoEvent里會獲取audio的時間戳,是傳統的AV時間戳做同步。
4.1》AwesomePlayer的Video主要有以下幾個成員:
mVideoSource(解碼視頻)
mVideoTrack(從多媒體文件中讀取視頻數據)
mVideoRenderer(對解碼好的視頻進行格式轉換,android使用的格式為RGB565)
mISurface(重繪圖層)
mQueue(event事件隊列)
4.2》stagefright運行時的Audio部分抽象流程如下:
設置mUri的路徑
啟動mQueue,創建一個線程來運行 threadEntry(命名為TimedEventQueue,這個線程就是event調度器)
打開mUri所指定的文件的頭部,則會根據類型選擇不同的分離器(如MPEG4Extractor)
使用 MPEG4Extractor對MP4進行音視頻軌道的分離,並返回MPEG4Source類型的視頻軌道給mVideoTrack
根據 mVideoTrack中的編碼類型來選擇解碼器,avc的編碼類型會選擇AVCDecoder,並返回給mVideoSource,並設置mVideoSource中的mSource為mVideoTrack
插入onVideoEvent到Queue中,開始解碼播放
通過mVideoSource對象來讀取解析好的視頻buffer
如果解析好的buffer還沒到AV時間戳同步的時刻,則推遲到下一輪操作
mVideoRenderer為空,則進行初始化(如果不使用 OMX會將mVideoRenderer設置為AwesomeLocalRenderer)
通過mVideoRenderer對象將解析好的視頻buffer轉換成RGB565格式,並發給display模塊進行圖像繪制
將onVideoEvent重新插入event調度器來循環
4.3》數據由源到最終解碼後的流程如下:
URI,FD
|
DataSource
|
MediaExtractor
|
mVideoTrack mAudioTrack//音視頻數據流
|
mVideoSource mAudioSource//音視頻解碼器
| |
mVideoBuffer mAudioPlayer
說明:
設置DataSource,數據源可以兩種URI和FD。URI可以http://,rtsp://等。FD是一個本地文件描述符,能過FD,可以找到對應的文件。
由DataSource生成MediaExtractor。通過sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);來實現。 MediaExtractor::Create(dataSource)會根據不同的數據內容創建不同的數據讀取對象。
通過調用setVideoSource由MediaExtractor分解生成音頻數據流(mAudioTrack)和視頻數據流(mVideoTrack)。
onPrepareAsyncEvent()如果DataSource是URL的話,根據地址獲取數據,並開始緩沖,直到獲取到mVideoTrack和mAudioTrack。mVideoTrack和mAudioTrack通過調用initVideoDecoder()和initAudioDecoder()來生成 mVideoSource和mAudioSource這兩個音視頻解碼器。然後調用postBufferingEvent_l()提交事件開啟緩沖。
數據緩沖的執行函數是onBufferingUpdate()。緩沖區有足夠的數據可以播放時,調用play_l()開始播放。play_l()中關鍵是調用了postVideoEvent_l(),提交了 mVideoEvent。這個事件執行時會調用函數onVideoEvent()。這個函數通過調用 mVideoSource->read(&mVideoBuffer, &options)進行視頻解碼。音頻解碼通過mAudioPlayer實現。
視頻解碼器解碼後通過mVideoSource->read讀取一幀幀的數據,放到mVideoBuffer中,最後通過 mVideoRenderer->render(mVideoBuffer)把視頻數據發送到顯示模塊。當需要暫停或停止時,調用cancelPlayerEvents來提交事件用來停止解碼,還可以選擇是否繼續緩沖數據。
5、 代碼標記Log
依據第4》項StageFright描述的Vide視頻播放流程,作Log標記跟蹤視頻DATA獲取、CODEC過程。從AwesomePlayer.cpp中方法著手,步驟如下:
在修改的/mydroid/frameworks/base/media/libstagefrigh/下,用mm編譯,並調試直到生成相應的.so文件。註:允許單模塊編譯時,需事先在/mydroid下允許. ./build/envsetup.sh文件。
在/mydroid/目錄下make進行整體編譯,生成system.img文件。說明:先單模塊編譯,後再整體編譯的好處是,可以縮短調試編譯的時間。
將system.img文件到/android-sdk-linux/platforms/android-8/下。注意:事先備份原有的system.img。
帶sdcard啟動模擬器,在/android-sdk-linux/tools/下運行./adb shell文件,再運行logcat
打開Gallery選擇視頻文件運行,並同步查看log。
反饋結果如下:
I/ActivityManager( 61): Starting: Intent { act=android.intent.action.VIEW dat=content://media/external/video/media/5 typ=video/mp4 cmp=com.cooliris.media/.MovieView } from pid 327
I/RenderView( 327): OnPause RenderView com.cooliris.media.RenderView@4054a3b0
E/AwesomePlayer( 34): beginning AwesomePlayer... by jay remarked...
E/AwesomePlayer( 34): returning AwesomeEvent...by jay remarked...
E/AwesomePlayer( 34): returning AwesomeEvent...by jay remarked...
E/AwesomePlayer( 34): returning AwesomeEvent...by jay remarked...
E/AwesomePlayer( 34): returning AwesomeEvent...by jay remarked...
E/AwesomePlayer( 34): ending AwesomePlayer... by jay remarked...
E/AwesomePlayer( 34): setting video source now... by jay remarked...
E/AwesomePlayer( 34): setting Video Type... by jay remarked...
E/AwesomePlayer( 34): returning AwesomeEvent...by jay remarked...
E/AwesomePlayer( 34): beginning initVideoDecoder by jay remarked...
D/MediaPlayer( 327): getMetadata
I/ActivityManager( 61): Displayed com.cooliris.media/.MovieView: +1s761ms
E/AwesomePlayer( 34): beginning AwesomeLocalRenderer init ...by jay remarked...
E/AwesomePlayer( 34): returning open(libstagefrighthw.so) correctly by jay remarked...
E/MemoryHeapBase( 34): error opening /dev/pmem_adsp: No such file or directory
I/SoftwareRenderer( 34): Creating physical memory heap failed, reverting to regular heap.
E/AwesomePlayer( 34): ending AwesomeLocalRenderer init close ...by jay remarked...
E/AwesomePlayer( 34): returning AwesomeLocalRenderer...by jay remarked...
I/CacheService( 327): Starting CacheService
Ⅵ android4.4 stagefright 支持 rtsp嗎
1.source:數據源,數據的來源不一定都是本地file,也有可能是網路上的各種協議例如:http、rtsp、HLS等。source的任務就是把數據源抽象出來,為下一個demux模塊提供它需要的穩定的數據流。demux不用關信數據到底是從什麼地方來的。
2.demux解復用:視頻文件一般情況下都是把音視頻的ES流交織的通過某種規則放在一起。這種規則就是容器規則。現在有很多不同的容器格式。如ts、mp4、flv、mkv、avi、rmvb等等。demux的功能就是把音視頻的ES流從容器中剝離出來,然後分別送到不同的解碼器中。其實音頻和視頻本身就是2個獨立的系統。容器把它們包在了一起。但是他們都是獨立解碼的,所以解碼之前,需要把它分別 獨立出來。demux就是干這活的,他為下一步decoder解碼提供了數據流。
3.decoder解碼:解碼器--播放器的核心模塊。分為音頻和視頻解碼器。影像在錄制後, 原始的音視頻都是佔用大量空間, 而且是冗餘度較高的數據. 因此, 通常會在製作的時候就會進行某種壓縮 ( 壓縮技術就是將數據中的冗餘信息去除數據之間的相關性 ). 這就是我們熟知的音視頻編碼格式, 包括MPEG1(VCD)/ MPEG2(DVD)/ MPEG4 / H.264 等等. 音視頻解碼器的作用就是把這些壓縮了的數據還原成原始的音視頻數據. 當然, 編碼解碼過程基本上都是有損的 .解碼器的作用就是把編碼後的數據還原成原始數據。
4.output輸出:輸出部分分為音頻和視頻輸出。解碼後的音頻(pcm)和視頻(yuv)的原始數據需要得到音視頻的output模塊的支持才能真正的讓人的感官系統(眼和耳)辨識到。
所以,播放器大致分成上述4部分。怎麼抽象的實現這4大部分、以及找到一種合理的方式將這幾部分組織並運動起來。是每個播放器不同的實現方式而已。