播放HLS时,部分TS分片的sps排列是: 0 0 0 1 9 240 0 0 0 1 103 。。。 0 0 0 1 104。。。 其对应的内容是:
- 0 0 0 1 9 240 :表示AUD
- 接着的 0 0 0 1 :表示 start code
- 接着的103 :表示sps类型
- 接着的就是sps的数据
- 最后的0 0 0 1 104 :104表示是pps数据
- 接着的就是pps的数据
这里针对这种情况做了处理,提取出其中的sps数据给到MediaCodec,避免MediaCodec初始化失败。
需要这种视频链接的,我可以发出来,不过视频链接只有24小时有效。
issues如下:
- android k0.8.4 某些手机播放视频有声音,无画面(即透明,非黑屏)?#4177
- 请教下Android播放视频只有声音没有画面??#3544
ijkmedia/ijkplayer/android/pipeline/ffpipenode_android_mediacodec_vdec.c
@@ -245,24 +245,23 @@ static int recreate_format_l(JNIEnv *env, IJKFF_Pipenode *node)
SDL_AMediaFormat_setBuffer(opaque->input_aformat, "csd-0", convert_buffer, esds_size);
free(convert_buffer);
} else {
//先只考虑h264的情况,H265这种情况我也没见过
if(opaque->avctx->codec_id == AV_CODEC_ID_H264 && opaque->avctx->extradata_size > 6){
//参考 https://blog.csdn.net/chinabinlang/article/details/78181110
//参考 https://blog.csdn.net/dxpqxb/article/details/7631644
//这种视频是:AUD+SPS+PPS的情况
if(opaque->codecpar->codec_id == AV_CODEC_ID_H264 && opaque->codecpar->extradata_size > 6){
// https://blog.csdn.net/chinabinlang/article/details/78181110
// https://blog.csdn.net/dxpqxb/article/details/7631644
// AUD+SPS+PPS的情况
// 103 代表sps
// 104 代表pps
int spsIndex = -1;
int ppsIndex = -1;
if(opaque->avctx->extradata[0] == 0 && opaque->avctx->extradata[1] == 0 && opaque->avctx->extradata[2] == 0
&& opaque->avctx->extradata[3] == 1 && opaque->avctx->extradata[4] == 9 && opaque->avctx->extradata[5] == 240){
if(opaque->codecpar->extradata[0] == 0 && opaque->codecpar->extradata[1] == 0 && opaque->codecpar->extradata[2] == 0
&& opaque->codecpar->extradata[3] == 1 && opaque->codecpar->extradata[4] == 9 && opaque->codecpar->extradata[5] == 240){
for(int i=6;i<opaque->avctx->extradata_size-4;i++){
if(opaque->avctx->extradata[i] == 0 && opaque->avctx->extradata[i+1] == 0 && opaque->avctx->extradata[i+2] == 0
&& opaque->avctx->extradata[i+3] == 1){
if(opaque->avctx->extradata[i+4] == 103){
if(opaque->codecpar->extradata[i] == 0 && opaque->codecpar->extradata[i+1] == 0 && opaque->codecpar->extradata[i+2] == 0
&& opaque->codecpar->extradata[i+3] == 1){
if(opaque->codecpar->extradata[i+4] == 103){
spsIndex = i;
ALOGE("AMediaFormat find sps = %d",spsIndex);
}else if(opaque->avctx->extradata[i+4] == 104){
}else if(opaque->codecpar->extradata[i+4] == 104){
ppsIndex = i;
ALOGE("AMediaFormat find pps = %d",ppsIndex);
}
@@ -275,11 +274,11 @@ static int recreate_format_l(JNIEnv *env, IJKFF_Pipenode *node)
if(ppsIndex > 0 && spsIndex < ppsIndex){
length = ppsIndex-spsIndex;
}else{
length = opaque->avctx->extradata_size-spsIndex;
length = opaque->codecpar->extradata_size-spsIndex;
}
uint8_t *convert_buffer = (uint8_t *)calloc(1, length);
memcpy( convert_buffer, opaque->avctx->extradata+spsIndex, length);
memcpy( convert_buffer, opaque->codecpar->extradata+spsIndex, length);
SDL_AMediaFormat_setBuffer(opaque->input_aformat, "csd-0", convert_buffer, length);
free(convert_buffer);
获取MediaCodec的SPS和PPS
一、SPS和PPS文档说明
二、NALU类型
三、获取SPS、PPS两种方式?1、同步方式
ByteBuffer spsb = videoEncodec.getOutputFormat().getByteBuffer("csd-0");
byte[] sps = new byte[spsb.remaining()];
spsb.get(sps, 0, sps.length);
ByteBuffer ppsb = videoEncodec.getOutputFormat().getByteBuffer("csd-1");
byte[] pps = new byte[ppsb.remaining()];
ppsb.get(pps, 0, pps.length);
2、异步方式
@Override
public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {
? ? MediaFormat outputFormat = codec.getOutputFormat();
? ? SPS = outputFormat.getByteBuffer("csd-0").array();
? ? PPS = outputFormat.getByteBuffer("csd-1").array();
? ? Log.e(TAG," onOutputFormatChanged ?SPS ?"+ CommonUtils.byteToHex(SPS));
? ? Log.e(TAG," onOutputFormatChanged ?PPS ?"+CommonUtils.byteToHex(PPS));
}
四、对应的sps、pps、I帧、P帧等数据
1、sps、pps
sps:000000016742ffffffc01effffffda05ffffffc145ffffff97ffffff8078402150
pps:0000000168ffffffce3cffffff80
2、I帧
data:0000000165ffffffb80010ffffffa413ffffffffffffffe5ffffffc3ffffffd31239695affffffabffffffb0340a
3、P帧
data:0000000161ffffffe9ffffffab13ffffffcd72ffffffdbffffffe5ffffffe25f5d7e64ffffff9ffffffff33affffffebffffffbd
总结:编码器编出来的数据首帧、sps、pps、I帧、P帧等顺序 ?
利用MediaCodec 获取视频的sps pps 和视频数据_we1less的博客-CSDN博客
|