Skip to content
Snippets Groups Projects
Commit c617aff8 authored by Jeffer's avatar Jeffer
Browse files

only search startcode 4 byte(00 00 00 01 standard h264 encoder) in searchAnnexb

parent 02733524
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -613,38 +613,49 @@ public class SrsFlvMuxer {
return allocation;
}
 
private SrsAnnexbSearch searchAnnexb(ByteBuffer bb, MediaCodec.BufferInfo bi) {
private SrsAnnexbSearch searchStartcode(ByteBuffer bb, MediaCodec.BufferInfo bi) {
annexb.match = false;
annexb.nb_start_code = 0;
if (bi.size - 4 > 0) {
if (bb.get(0) == 0x00 && bb.get(1) == 0x00 && bb.get(2) == 0x00 && bb.get(3) == 0x01) {
// match N[00] 00 00 00 01, where N>=0
annexb.match = true;
annexb.nb_start_code = 4;
}
}
return annexb;
}
 
private SrsAnnexbSearch searchAnnexb(ByteBuffer bb, MediaCodec.BufferInfo bi) {
annexb.match = false;
annexb.nb_start_code = 0;
for (int i = bb.position(); i < bi.size - 3; i++) {
// not match.
if (bb.get(i) != 0x00 || bb.get(i + 1) != 0x00) {
if (bb.get(i) != 0x00 || bb.get(i + 1) != 0x00 || bb.get(i + 2) != 0x00) {
break;
}
// match N[00] 00 00 01, where N>=0
if (bb.get(i + 2) == 0x01) {
if (bb.get(i + 3) == 0x01) {
annexb.match = true;
annexb.nb_start_code = i + 3 - bb.position();
annexb.nb_start_code = i + 4 - bb.position();
break;
}
}
return annexb;
}
 
public SrsFlvFrameBytes demuxAnnexb(ByteBuffer bb, MediaCodec.BufferInfo bi) {
public SrsFlvFrameBytes demuxAnnexb(ByteBuffer bb, MediaCodec.BufferInfo bi, boolean isOnlyChkHeader) {
SrsFlvFrameBytes tbb = new SrsFlvFrameBytes();
 
while (bb.position() < bi.size) {
if (bb.position() < bi.size) {
// each frame must prefixed by annexb format.
// about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
SrsAnnexbSearch tbbsc = searchAnnexb(bb, bi);
SrsAnnexbSearch tbbsc = isOnlyChkHeader?searchStartcode(bb, bi):searchAnnexb(bb, bi);
// tbbsc.nb_start_code always 4 , after 00 00 00 01
if (!tbbsc.match || tbbsc.nb_start_code < 3) {
Log.e(TAG, "annexb not match.");
mHandler.notifyRtmpIllegalArgumentException(new IllegalArgumentException(
String.format("annexb not match for %dB, pos=%d", bi.size, bb.position())));
// mHandler.notifyRtmpIllegalArgumentException(new IllegalArgumentException(
// String.format("annexb not match for %dB, pos=%d", bi.size, bb.position())));
}
 
// the start codes.
Loading
Loading
@@ -654,17 +665,7 @@ public class SrsFlvMuxer {
 
// find out the frame size.
tbb.data = bb.slice();
int pos = bb.position();
while (bb.position() < bi.size) {
SrsAnnexbSearch bsc = searchAnnexb(bb, bi);
if (bsc.match) {
break;
}
bb.get();
}
tbb.size = bb.position() - pos;
break;
tbb.size = bi.size - bb.position();
}
 
return tbb;
Loading
Loading
@@ -850,57 +851,40 @@ public class SrsFlvMuxer {
 
int type = SrsCodecVideoAVCFrame.InterFrame;
 
// send each frame.
while (bb.position() < bi.size) {
SrsFlvFrameBytes frame = avc.demuxAnnexb(bb, bi);
// 5bits, 7.3.1 NAL unit syntax,
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
int nal_unit_type = (int)(frame.data.get(0) & 0x1f);
if (nal_unit_type == SrsAvcNaluType.SPS || nal_unit_type == SrsAvcNaluType.PPS) {
Log.i(TAG, String.format("annexb demux %dB, pts=%d, frame=%dB, nalu=%d",
bi.size, pts, frame.size, nal_unit_type));
}
// for IDR frame, the frame is keyframe.
if (nal_unit_type == SrsAvcNaluType.IDR) {
type = SrsCodecVideoAVCFrame.KeyFrame;
if (bi.size < 4) return;
SrsFlvFrameBytes frame = avc.demuxAnnexb(bb, bi, true);
int nal_unit_type = (int)(frame.data.get(0) & 0x1f);
if (nal_unit_type == SrsAvcNaluType.NonIDR)
{
} else if (nal_unit_type == SrsAvcNaluType.IDR)
{
type = SrsCodecVideoAVCFrame.KeyFrame;
} else if (nal_unit_type == SrsAvcNaluType.SPS || nal_unit_type == SrsAvcNaluType.PPS)
{
if (!frame.data.equals(h264_sps)) {
byte[] sps = new byte[frame.size];
frame.data.get(sps);
h264_sps_changed = true;
h264_sps = ByteBuffer.wrap(sps);
writeH264SpsPps(dts, pts);
}
// ignore the nalu type aud(9)
if (nal_unit_type == SrsAvcNaluType.AccessUnitDelimiter) {
continue;
}
// for sps
if (avc.isSps(frame)) {
if (!frame.data.equals(h264_sps)) {
byte[] sps = new byte[frame.size];
frame.data.get(sps);
h264_sps_changed = true;
h264_sps = ByteBuffer.wrap(sps);
}
continue;
}
// for pps
if (avc.isPps(frame)) {
if (!frame.data.equals(h264_pps)) {
byte[] pps = new byte[frame.size];
frame.data.get(pps);
h264_pps_changed = true;
h264_pps = ByteBuffer.wrap(pps);
}
continue;
frame = avc.demuxAnnexb(bb, bi, false);
if (!frame.data.equals(h264_pps)) {
byte[] pps = new byte[frame.size];
frame.data.get(pps);
h264_pps_changed = true;
h264_pps = ByteBuffer.wrap(pps);
writeH264SpsPps(dts, pts);
}
return;
} else
return;
 
// IPB frame.
ipbs.add(avc.muxNaluHeader(frame));
ipbs.add(frame);
}
ipbs.add(avc.muxNaluHeader(frame));
ipbs.add(frame);
 
writeH264SpsPps(dts, pts);
//writeH264SpsPps(dts, pts);
writeH264IpbFrame(ipbs, type, dts, pts);
ipbs.clear();
}
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment