2014-10-07 36 views
0

我正在使用JavaCPP av_read_packet從H264(MPEG4 AVC)源讀取AVPackets,然後我試圖僅將視頻數據包傳遞給Android的MediaCodec以解碼它們並將其渲染爲Surface(用於顯示)。 我讀過使用av_bitstream_filter_filter和h264_mp4toannexb過濾器時需要使用AVC源與MediaCodec兼容。AVPacket到Android MediaCodec

問題是,dequeueOutputBuffer總是返回-1,我不知道問題是在使用過濾器還是其他原因時。

以下是代碼片段:

bsfc = new AVBitStreamFilterContext(); 
bsfc = av_bitstream_filter_init("h264_mp4toannexb"); 

public void FilterPacket(AVPacket paquete){ 

    IntPointer size_pointer = new IntPointer(1); 
    size_pointer.put(paquete.size()); 
    BytePointer data = new BytePointer(); 

    int sal = av_bitstream_filter_filter(bsfc, video_codec, (BytePointer)null, data, size_pointer, paquete.data(), paquete.size(), paquete.flags() & AV_PKT_FLAG_KEY); 

    paquete.size(size_pointer.get()); 
    paquete.data(data); 

} 

這裏是什麼解碼循環中:

public void DecoderLoop(AVPacket paquete){ 
    int inputBufferIndex = decoder.dequeueInputBuffer(5000); 
    if (inputBufferIndex >= 0) { 
     ByteBuffer bufferSalida = inputBuffers[inputBufferIndex]; 
     FilterPacket(paquete); 
     bufferSalida.put(paquete.data().asByteBuffer()); 
     //double presentationTemp = (double)(paquete.pts()/paquete.duration()) * (1000000/30); 
     //long presentationTime = (long)presentationTemp; 
     decoder.queueInputBuffer(inputBufferIndex, 0, paquete.size(), 0, 0); 

    } 

    int outputBufferIndex = decoder.dequeueOutputBuffer(info, 10000); 
    if (outputBufferIndex >= 0) { 
     // outputBuffer is ready to be processed or rendered. 
     decoder.releaseOutputBuffer(outputBufferIndex, true); 
    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { 
     outputBuffers = decoder.getOutputBuffers(); 
    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 
     // Subsequent data will conform to new format. 
     format = decoder.getOutputFormat(); 
    } 
} 

dequeueInputBuffer返回正值,且av_bitstream_filter_filter返回1(但我不知道它是否工作),但dequeueOutputBuffers總是返回-1。任何人都可以幫我解決問題嗎?

我懷疑問題可以是這些中的一個:

  • av_bitstream_filter_filter

  • bufferSalida.put(paquete.data()asByteBuffer()); ¿我可以用這些方法嗎?

  • 如果我使用.asByteBuffer,我可以使用paquete.size()還是我可以使用不同的東西?

非常感謝您

+0

也許http://bigflake.com/mediacodec/#q3? – fadden 2014-10-07 15:16:08

+0

在第三季度,他們通過MediaExtractor配置解碼器,但在這種情況下(沒有媒體提取器),我這樣配置: ' type =「video/avc」; decoder = MediaCodec.createDecoderByType(type); ... format = MediaFormat.createVideoFormat(type,codec_input.width(),codec_input.height()); decoder.configure(format,surface,null,0); decoder.start(); \t \t inputBuffers = decoder.getInputBuffers(); outputBuffers = decoder.getOutputBuffers();' – WotG 2014-10-07 16:03:09

+0

而我沒有BUFFER_FLAG_CODEC_CONFIG,因爲我沒有使用MediaDecoder。數據包來自javacpp的AVPackets – WotG 2014-10-07 16:11:42

回答

0

我不熟悉的libavcodec庫的這個JavaCPP包裝,但除了普通AVPackets,你需要AVCodecContext.extradata以及(初始化流過濾器後, ,並且在過濾第一個分組之後)。您需要將傳入的數據作爲ByteBuffer傳遞給傳遞的輸入MediaFormat中的名稱「csd-0」,或者在發送第一個AVPacket之前將其作爲單獨的緩衝區與BUFFER_FLAG_CODEC_CONFIG一起傳遞。

+0

fadden,你驅使我採用相同(正確)的方式。我需要在發送數據包之前正確配置解碼器。現在我不知道如何將這些信息傳遞給MediaFormat(在調用configure()方法之前),以及我需要的最小參數是什麼。但讓我們試試。非常感謝你 – WotG 2014-10-08 13:18:41