Skip to content

Commit 85072ac

Browse files
author
hide
committed
fix:couldn't play stream which openh264 encoded.
1 parent b303771 commit 85072ac

File tree

6 files changed

+133
-59
lines changed

6 files changed

+133
-59
lines changed

app/src/main/java/com/androidyuan/ui/MainActivity.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class MainActivity extends Activity implements SurfaceHolder.Callback,
3333
Camera mCamera;
3434
SurfaceHolder mPreviewHolder;
3535
byte[] mPreviewBuffer;
36-
//TODO get the compatible size from camera.
36+
//TODO obtain the a compatible set of size from camera.
3737
int width = 640;
3838
int height = 480;
3939
private final int VIDEOBITRATE = 512 *4;

openh264-codec/src/main/jni/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ add_library(
2929
softcodec/aacEncode.c
3030
softcodec/h264Encoder.cc
3131
softcodec/h264Encoder.h
32+
softcodec/print_hex.cc
3233

3334
# import lib rtmp code source.
3435
${RTMP_DIR}/amf.c

openh264-codec/src/main/jni/softcodec/h264Encoder.cc

+101-58
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,53 @@
22
#include "h264Encoder.h"
33
#include <iostream>
44
#include <string>
5+
#include "print_hex.h"
6+
57
static ISVCEncoder *_encoder;
68
static SEncParamExt param;
79

8-
9-
unsigned char sps[30];
10-
unsigned char pps[10];
11-
int first = 0;
10+
unsigned char *sps;
11+
unsigned char *pps;
1212
int sps_len;
1313
int pps_len;
1414

15+
/**
16+
*
17+
* @param NAL_type
18+
* @param buffer , must not begin with start-code such as "00 00 00 01"
19+
* @param len
20+
* @return
21+
*/
22+
int handle_sps_pps(int NAL_type, unsigned char *buffer, int len) {
23+
if (buffer[0] == 0) {
24+
ALOGE("buffer format is wrong.");
25+
return -1;
26+
}
27+
if (NAL_type == 7) {
28+
sps = buffer;
29+
sps_len = len;
30+
print_hex("SPS", sps, sps_len);
31+
} else if (NAL_type == 8) {
32+
pps = buffer;
33+
pps_len = len;
34+
send_video_sps_pps(sps, sps_len, pps, pps_len);
35+
print_hex("PPS", pps, pps_len);// print
36+
} else {
37+
ALOGE("It is not either SPS or PPS.");
38+
return -1;
39+
}
40+
41+
return 0;
42+
}
43+
44+
int handle_other_NAL(unsigned char *buffer, int len) {
45+
46+
send_rtmp_video(buffer,
47+
len,
48+
getSystemTime()); //into.uiTimeStamp
49+
return 0;
50+
}
51+
1552
#define RC_MARGIN 10000 /*bits per sec*/
1653
extern "C" JNIEXPORT jlong
1754
Java_io_github_brucewind_softcodec_StreamHelper_compressBegin(JNIEnv *env,
@@ -35,7 +72,7 @@ Java_io_github_brucewind_softcodec_StreamHelper_compressBegin(JNIEnv *env,
3572
param.bEnableDenoise = 1; //enable eliminating noisy.
3673
param.iSpatialLayerNum = 1;
3774
//if (sliceMode != SM_SINGLE_SLICE && sliceMode != SM_DYN_SLICE) //SM_DYN_SLICE don't support multi-thread now
38-
param.iMultipleThreadIdc = 2;
75+
// param.iMultipleThreadIdc = 2;
3976
for (int i = 0; i < param.iSpatialLayerNum; i++) {
4077
param.sSpatialLayers[i].iVideoWidth = width >> (param.iSpatialLayerNum - 1 - i);
4178
param.sSpatialLayers[i].iVideoHeight = height >> (param.iSpatialLayerNum - 1 - i);
@@ -64,7 +101,6 @@ Java_io_github_brucewind_softcodec_StreamHelper_compressEnd(
64101
jobject thiz,
65102
jlong handle
66103
) {
67-
first = 0;
68104
return 0;
69105
}
70106

@@ -96,7 +132,7 @@ extern "C" JNIEXPORT jint Java_io_github_brucewind_softcodec_StreamHelper_compr
96132
ISVCEncoder *en = (ISVCEncoder *) _encoder;
97133

98134
int i_data = 0;
99-
int count_of_NALU = -1;//A frame may be separated into saveral NALU.
135+
int count_of_NALU = -1;//A frame may be separated into several NALUs.
100136
int result = 0;
101137
int i = 0;
102138
int i_frame_size = 0;
@@ -110,34 +146,17 @@ extern "C" JNIEXPORT jint Java_io_github_brucewind_softcodec_StreamHelper_compr
110146

111147

112148
//1. the first step: encode header with PPS & SPS.
113-
if(first == 0) {
114-
SFrameBSInfo fbi = {0};
115-
int pps_suc = _encoder->EncodeParameterSets(&fbi);
116-
if (pps_suc != 0) {
117-
ALOGE("PPS & SPS encoding got failed.");
118-
return -1;
119-
}
120-
121-
fbi.sLayerInfo[0].pBsBuf+=4;
122-
unsigned char* sps_raw = fbi.sLayerInfo[0].pBsBuf;
123-
const auto sps_len =fbi.sLayerInfo[0].pNalLengthInByte[0]-4;
124-
fbi.sLayerInfo[0].pBsBuf+=sps_len;
125-
ALOGI("sLayerInfo[0].iNalCount :%d", fbi.sLayerInfo[0].iNalCount);
126-
if(fbi.sLayerInfo[0].iNalCount>1){
127-
fbi.sLayerInfo[0].pBsBuf+=4;
128-
unsigned char* pps_raw = fbi.sLayerInfo[0].pBsBuf;
129-
const auto pps_len =fbi.sLayerInfo[0].pNalLengthInByte[1]-4;
130-
131-
ALOGD("SPS len: %d , PPS len: %d .",sps_len,pps_len);
132-
send_video_sps_pps(sps_raw,sps_len,pps_raw,pps_len);
133-
first = 1;
134-
}
135-
else{
136-
ALOGE("Reject: there is no PPS NAL.");
137-
return -1;
138-
}
149+
// if (first == 0) {
150+
// SFrameBSInfo fbi = {0};
151+
// int pps_suc = _encoder->EncodeParameterSets(&fbi);
152+
// if (pps_suc != 0) {
153+
// ALOGE("PPS & SPS encoding got failed.");
154+
// return -1;
155+
// }
156+
//
157+
// handle_sps_pps(fbi);
139158

140-
}
159+
// }
141160

142161

143162
//encode and store ouput bistream
@@ -166,42 +185,66 @@ extern "C" JNIEXPORT jint Java_io_github_brucewind_softcodec_StreamHelper_compr
166185
}
167186
return -1;
168187
}
169-
170-
if(info.eFrameType == videoFrameTypeInvalid){
171-
ALOGE("videoFrameTypeInvalid");
172-
return 0;
173-
}
174-
// else if (info.eFrameType == videoFrameTypeSkip) {//it need to skip.
175-
// ALOGW("skip this frame");
176-
// return 0;
177-
// }
178-
else {
179-
ALOGD("foreach NAL type : %d., laytype is %d.", info.sLayerInfo[i].eFrameType,info.sLayerInfo[i].uiLayerType);
180-
}
181-
182188
if (info.iLayerNum <= 0) {
183189
ALOGE("something wrong in \"i_frame_size < 0\".");
184190
return -1;
185191
}
192+
if (info.iLayerNum > 1) {
193+
ALOGI("data lost due to that iLayerNum=%d.", info.iLayerNum);
194+
}
195+
if (info.eFrameType == videoFrameTypeInvalid) {
196+
ALOGE("videoFrameTypeInvalid");
197+
return 0;
198+
} else if (info.eFrameType == videoFrameTypeSkip) {//it need to skip.
199+
ALOGW("skip this frame");
200+
return 0;
201+
} else {
202+
ALOGD("foreach NAL type : %d., laytype is %d.", info.sLayerInfo[i].eFrameType,
203+
info.sLayerInfo[i].uiLayerType);
204+
}
205+
186206

187207
/**
188208
* 2. The second step:
189209
* transmit serveral NALUs to RTMP server.
190210
* Two NAL types : SPS & PPS are very important.
191211
*/
192212
for (i = 0; i < info.iLayerNum; i++) {//iLayerNum is the count of NALUs.
193-
int type = info.sLayerInfo[i].eFrameType;//it is NON_VIDEO_CODING_LAYER
194-
195-
if (info.sLayerInfo[i].uiLayerType == NON_VIDEO_CODING_LAYER) {//this NAL type is SPS.
196-
213+
// int type = info.sLayerInfo[i].eFrameType;//it is NON_VIDEO_CODING_LAYER
214+
//
215+
// if (info.sLayerInfo[i].uiLayerType == NON_VIDEO_CODING_LAYER) {//this NAL type is SPS.
216+
// }
217+
const SLayerBSInfo layerInfo = info.sLayerInfo[i];
218+
unsigned char *buffer = layerInfo.pBsBuf;
219+
for (auto index_nal = 0; index_nal < layerInfo.iNalCount; index_nal++) {
220+
221+
const int buf_len = layerInfo.pNalLengthInByte[index_nal];
222+
//detect NAL
223+
int NAL_type = 0;
224+
int start_len = 0;
225+
if (buffer[2] == 0x00) { /*00 00 00 01*/
226+
NAL_type = buffer[4] & 0x1f;
227+
start_len = 4;
228+
} else if (buffer[2] == 0x01) { /*00 00 01*/
229+
NAL_type = buffer[3] & 0x1f;
230+
start_len = 3;
231+
} else {
232+
if (buffer[0] != 0) {
233+
NAL_type = buffer[0] & 0x1f;
234+
} else {
235+
result = 1;
236+
ALOGE("start code not found.");
237+
}
238+
}
239+
if (NAL_type == 7 || NAL_type == 8) {
240+
buffer += start_len;
241+
handle_sps_pps(NAL_type, buffer, buf_len - start_len);
242+
buffer+=(buf_len - start_len);
243+
} else {
244+
handle_other_NAL(buffer, buf_len);
245+
buffer += buf_len;
246+
}
197247
}
198-
else {//TODO
199-
200-
}
201-
202-
send_rtmp_video(info.sLayerInfo[i].pBsBuf,
203-
info.sLayerInfo[i].pNalLengthInByte[0],
204-
getSystemTime()); //into.uiTimeStamp
205248
ALOGD("send_rtmp_video() end");
206249

207250
//release buffers.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <string.h>
2+
#include <jni.h>
3+
#include <stdio.h>
4+
#include <stdint.h>
5+
#include <android/log.h>
6+
#include <iostream>
7+
#include <string>
8+
#include "h264_encoder_log.h"
9+
10+
void print_hex(char * tag, unsigned char* data,int len){
11+
char buffer[len*2+1];
12+
buffer[len*2]=0;
13+
14+
for(auto j = 0; j < len; j++){
15+
sprintf(&buffer[2*j], "%02X", data[j]);
16+
}
17+
ALOGI("%s hex:%s",tag,buffer);
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//
2+
// Created by bruce on 21-6-14.
3+
//
4+
5+
#ifndef SOFTCODEC_PRINT_HEX_H
6+
#define SOFTCODEC_PRINT_HEX_H
7+
8+
void print_hex(char * tag, unsigned char* data,int len);
9+
#endif //SOFTCODEC_PRINT_HEX_H

openh264-codec/src/main/jni/softcodec/xiecc_rtmp.c

+3
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ void send_rtmp_video(uint8_t *data, uint32_t data_len, int timestamp) {
142142
LOGE("start code not found.");
143143
}
144144
type = buffer[0] & 0x1f;
145+
if(type>1) {
146+
LOGE("this type is %d.", type);
147+
}
145148
packet = (RTMPPacket *) malloc(RTMP_HEAD_SIZE + length + 9);
146149
memset(packet, 0, RTMP_HEAD_SIZE);
147150

0 commit comments

Comments
 (0)