2014-10-03 73 views
2

我還沒有發現的M3U8文件的HW解碼(即流媒體直播),我已經問了一下在一個解決方案:股票Android的H264解碼器失敗的.m3u8 URL文件

ACodec call to OMX_GetExtensionIndex fails, during playback of an m3u8 file

所以,我決定嘗試強制使用谷歌的股票SW解碼爲ACodedc:

bool ACodec::UninitializedState::onAllocateComponent 
    ... 
    OMXCodec::findMatchingCodecs(
      mime.c_str(), 
      encoder, // createEncoder 
      NULL, // matchComponentName 
      kSoftwareCodecsOnly, // Forcing SW for ACodec i.e. live streaming 
      &matchingCodecs, 
      &matchingCodecQuirks); 

但它墜毀...好像緩衝大小(91286),比信息 - > mData->容量(65536)大,在緩衝區分配上給出:

V/ACodec ( 74): [OMX.google.h264.decoder] Allocating 8 buffers of size 65536 on input port 

緩衝區大小會從這些片段,在Acodec.cpp:

ACodec::setupVideoEncoder 
... 
def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3)/2; 

ACodec::setVideoFormatOnPort 
... 
if (portIndex == kPortIndexInput) { 
    // XXX Need a (much) better heuristic to compute input buffer sizes. 
    const size_t X = 64 * 1024; 
    if (def.nBufferSize < X) { 
     def.nBufferSize = X; 
    } 
} 

我改變了這種邏輯如下圖所示,只需加倍尺寸:

const size_t X = 128 * 1024; 

這使得它去線槽INTIAL階段但之後由於另一原因而失敗:

V/MediaPlayer(1040): setDataSource(http://everyrai-lh.akamaihd.net/i/[email protected]/master.m3u8) 
V/MediaPlayerService( 74): Client(8) constructor 
V/MediaPlayerService( 74): Create new client(8) from pid 1040, uid 10064, 
V/MediaPlayerService( 74): setDataSource(http://everyrai-lh.akamaihd.net/i/[email protected]/master.m3u8) 
... 
V/ACodec ( 74): Increasing nBufferSize to 131072 
V/ACodec ( 74): setVideoFormatOnPort 
V/ACodec ( 74): ComponentName: OMX.google.h264.decoder 
V/ACodec ( 74): onStart 
V/ACodec ( 74): [OMX.google.h264.decoder] Now Loaded->Idle 
V/ACodec ( 74): [OMX.google.h264.decoder] Allocating 8 buffers of size 131072 on input port 
V/ACodec ( 74): [OMX.google.h264.decoder] Allocating 2 buffers of size 115200 on output port 
V/ACodec ( 74): [OMX.google.h264.decoder] Now Idle->Executing 
V/ACodec ( 74): [OMX.google.h264.decoder] calling fillBuffer 0x2a085a80 
V/ACodec ( 74): [OMX.google.h264.decoder] calling fillBuffer 0x2a085c58 
V/ACodec ( 74): [OMX.google.h264.decoder] Now Executing 
V/ACodec ( 74): [OMX.google.h264.decoder] calling emptyBuffer 0x2a089e30 w/ codec specific data 
V/ACodec ( 74): [OMX.google.h264.decoder] onOMXEmptyBufferDone 0x2a089e30 
V/ACodec ( 74): [OMX.google.h264.decoder] calling emptyBuffer 0x2a099d50 w/ codec specific data 
V/ACodec ( 74): [OMX.google.h264.decoder] calling emptyBuffer 0x2a089e30 w/ time 240000 us 
E/SoftAVC ( 74): Decoder failed: -2 
V/ACodec ( 74): [OMX.google.h264.decoder] onOMXEmptyBufferDone 0x2a099d50 
V/ACodec ( 74): [OMX.google.h264.decoder] calling emptyBuffer 0x2a099c50 w/ time 360000 us 
E/ACodec ( 74): [OMX.google.h264.decoder] ERROR(0x80001001) 
... 

A在h264dec /源dding一些跟蹤日誌,我得到了這些額外的信息:

D/H264Dec ( 75): H264SwDecInit# 
D/H264Dec ( 75): H264SwDecInit# decInst 0x2a075448 noOutputReordering 0 
D/H264Dec ( 75): H264SwDecInit# OK: return 0x2a0758a8 
D/H264Dec ( 75): H264SwDecDecode# 
D/H264Dec ( 75): H264SwDecDecode# decInst 0x2a0758a8 pInput 0x42b6dd88 pOutput 0x42b6dd7c 
D/H264Dec ( 75): H264SwDecDecode# OK: DecResult 1 
D/H264Dec ( 75): H264SwDecDecode# 
D/H264Dec ( 75): H264SwDecDecode# decInst 0x2a0758a8 pInput 0x42b6dd88 pOutput 0x42b6dd7c 
D/H264Dec ( 75): H264SwDecDecode# OK: DecResult 1 
D/H264Dec ( 75): H264SwDecDecode# 
D/H264Dec ( 75): H264SwDecDecode# decInst 0x2a0758a8 pInput 0x42b6dd88 pOutput 0x42b6dd7c 
D/H264Dec ( 75): H264SwDecDecode# OK: DecResult -2 
E/SoftAVC ( 75): Decoder failed: -2 
I/SoftAAC2( 75): Reconfiguring decoder: 44100 Hz, 2 channels 
E/ACodec ( 75): [OMX.google.h264.decoder] ERROR(0x80001001) 
E/NuPlayer( 75): Received error from video decoder, aborting playback. 

在這裏, 「DecResult -2」 是H264SWDEC_STRM_ERR從這個代碼片段:

decResult = h264bsdDecode(&pDecCont->storage, tmpStream, strmLen, 
    ... 
    switch (decResult) 
    { 
    ... 
     case H264BSD_PARAM_SET_ERROR: 
      if (!h264bsdCheckValidParamSets(&pDecCont->storage) && 
       strmLen == 0) 
      { 
       returnValue = H264SWDEC_STRM_ERR; 

我想,首先所有的,爲什麼股票解碼器不能使用標準的流媒體URL(底層應用在其他設備上工作)。

我對緩衝區「調整大小」的猜測是否正確?我不知道它爲什麼失敗,採用默認的大小調整邏輯。

有關最新錯誤的任何建議/修復?

它可能與上面的大小錯誤有關嗎?

感謝 法比奧

回答

1

無關,與規模以上劈...非常第一個錯誤我得到的是:

E/H264_pps( 75): entropy_coding_mode_flag 
E/H264_decoder( 75): PIC_PARAM_SET 

,它是由h264bsd_pic_param_set.c的代碼段:

/* entropy_coding_mode_flag, shall be 0 for baseline profile */ 
tmp = h264bsdGetBits(pStrmData, 1); 
if (tmp) 
{ 
    EPRINT("entropy_coding_mode_flag"); 
    return(HANTRO_NOK); 
} 

查看H264文檔,我發現entropy_coding_mode_flag決定了兩種類型的編碼:

CAVLC: Context-based adaptive variable-length coding 
CABAC: Context-based adaptive binary arithmetic coding 

在這兩者中,CAVLC是質量較低,解碼更容易的選項,而CABAC是更高質量,更難解碼的選項。

多見於:

http://www.streaminglearningcenter.com/articles/producing-h264-video-for-flash-an-overview.html?page=3#sthash.26PqYA7p.dpuf

好像只有「基線分佈」是由AOSP解碼器所支持,而這裏我們與組的entropy_coding_mode_flag(即CABAC)編碼的流。

這可能是HW解碼器無法工作的原因 - 它不支持CABAC H264。

一種可能的解決方案可能來自於使用不同的SW編解碼器,例如,開放的「ffmpeg」,似乎工作得很好,通過MXPlayer應用程序播放完全相同的流。我想要的是讓股票播放器也使用這些編解碼器。

這些修補程序(在JB合併),整合在AOSP的ffmpeg解碼器,可能會做的伎倆:

https://github.com/omxcodec/stagefright-plugins(代碼)

雖然它尚未被應用和測試...