gpt4 book ai didi

Android Media Codec 视频解码

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:33:45 27 4
gpt4 key购买 nike

这是我的第一个问题,如果我遗漏了什么,请告诉我!

使用 Android API 16 的新媒体编解码器实现来尝试解码视频,以便我可以发送要作为纹理应用的帧(纹理部分已经完成)。因此,在堆栈外的一些帮助下,我想出了以下代码,但在 runOutputBuffer() 中,我的 outputBufIndex 返回了 -1(或在一个无限循环,因为我提供了 -1 作为超时)任何人都可以帮助解决这个问题,和/或提供关于从那里去哪里的任何建议?

感谢您的帮助,这是我的代码:

public MediaDecoder( BPRenderView bpview )
{

surface = bpview;
extractor = new MediaExtractor( );
extractor.setDataSource( filePath );
format = extractor.getTrackFormat( 0 );
mime = format.getString( MediaFormat.KEY_MIME );
createDecoder( );
runInputBuffer( );

}

public void createDecoder( )
{

codec = MediaCodec.createDecoderByType( "video/avc" );
// format =extractor.getTrackFormat( 0 );
Log.d( LOG_TAG, "Track Format: " + mime );
// format.setInteger( MediaFormat.KEY_BIT_RATE, 125000 );
// format.setInteger( MediaFormat.KEY_FRAME_RATE, 15 );
// format.setInteger( MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar );
// format.setInteger( MediaFormat.KEY_I_FRAME_INTERVAL, 5 );
codec.configure( format, null, null, 0 );
codec.start( );

codecInputBuffers = codec.getInputBuffers( );
codecOutputBuffers = codec.getOutputBuffers( );
extractor.selectTrack( 0 );
}

public void runInputBuffer( )
{
// This should take in the entire video and put it in the input buffer
int inputBufIndex = codec.dequeueInputBuffer( -1 );
if( inputBufIndex >= 0 )
{
ByteBuffer dstBuf = codecInputBuffers[ inputBufIndex ];

int sampleSize = extractor.readSampleData( dstBuf, 0 );
Log.d( "Sample Size", String.valueOf( sampleSize ) );
long presentationTimeUs = 0;
if( sampleSize < 0 )
{
sawInputEOS = true;
sampleSize = 0;
}
else
{
presentationTimeUs = extractor.getSampleTime( );
}
Log.d( LOG_TAG, "Input Buffer" );
Log.d( "InputBufIndex:", String.valueOf( inputBufIndex ) );
Log.d( "PresentationTimeUS", String.valueOf( presentationTimeUs ) );
codec.queueInputBuffer( inputBufIndex, 0, // offset
sampleSize, presentationTimeUs, sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0 );
if( !sawInputEOS )
{
Log.d( "Extractor", " Advancing" );
extractor.advance( );

}
}
runOutputBuffer( );
}

public void runOutputBuffer( )
{
BufferInfo info = new BufferInfo( );

final int res = codec.dequeueOutputBuffer( info, -1 );

Log.d( "RES: ", String.valueOf( res ) );
if( res >= 0 )
{
int outputBufIndex = res;
ByteBuffer buf = codecOutputBuffers[ outputBufIndex ];
final byte[ ] chunk = new byte[ info.size ];
buf.get( chunk ); // Read the buffer all at once
buf.clear( ); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN

if( chunk.length > 0 )
{
Log.d( "Chunk: ", String.valueOf( chunk.length ) );

surface.setTexture( chunk, 320, 240 );

// mAudioTrack.write( chunk, 0, chunk.length );
// do the things
}
codec.releaseOutputBuffer( outputBufIndex, false /* render */);

if( ( info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM ) != 0 )
{
sawOutputEOS = true;
}
}
else if( res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED )
{
codecOutputBuffers = codec.getOutputBuffers( );
}
else if( res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED )
{
final MediaFormat oformat = codec.getOutputFormat( );
Log.d( LOG_TAG, "Output format has changed to " + oformat );
// mAudioTrack.setPlaybackRate( oformat.getInteger( MediaFormat.KEY_SAMPLE_RATE ) );
}

}

最佳答案

James,欢迎来到 Stack Overflow(作为提问者)!

我试过玩弄 MediaCodec 类,它非常有限且文档不足。然而,看看这个漂亮的 solid post (和他链接的 github),作者 Cedric Fung。他的 github 项目应该在 API-17 (JellyBean 4.2)+ 设备上开箱即用。

我相信您可以从那里确定需要更改的内容,尽管正如我之前提到的那样,您在当前级别的 API 中的灵 active 有限。

关于您的具体问题,我认为您正在使用媒体解码器调用锁定 UI,不推荐这样做,您应该采用线程化方法,而不是将 -1 设置为超时,将超时设置为 10000并允许多次调用它直到它处于 Activity 状态。

希望这对您有所帮助(尽管您问这个问题已经几个月了)!

关于Android Media Codec 视频解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13567556/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com