2
2
#include " h264Encoder.h"
3
3
#include < iostream>
4
4
#include < string>
5
+ #include " print_hex.h"
6
+
5
7
static ISVCEncoder *_encoder;
6
8
static SEncParamExt param;
7
9
8
-
9
- unsigned char sps[30 ];
10
- unsigned char pps[10 ];
11
- int first = 0 ;
10
+ unsigned char *sps;
11
+ unsigned char *pps;
12
12
int sps_len;
13
13
int pps_len;
14
14
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
+
15
52
#define RC_MARGIN 10000 /* bits per sec*/
16
53
extern " C" JNIEXPORT jlong
17
54
Java_io_github_brucewind_softcodec_StreamHelper_compressBegin (JNIEnv *env,
@@ -35,7 +72,7 @@ Java_io_github_brucewind_softcodec_StreamHelper_compressBegin(JNIEnv *env,
35
72
param.bEnableDenoise = 1 ; // enable eliminating noisy.
36
73
param.iSpatialLayerNum = 1 ;
37
74
// 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;
39
76
for (int i = 0 ; i < param.iSpatialLayerNum ; i++) {
40
77
param.sSpatialLayers [i].iVideoWidth = width >> (param.iSpatialLayerNum - 1 - i);
41
78
param.sSpatialLayers [i].iVideoHeight = height >> (param.iSpatialLayerNum - 1 - i);
@@ -64,7 +101,6 @@ Java_io_github_brucewind_softcodec_StreamHelper_compressEnd(
64
101
jobject thiz,
65
102
jlong handle
66
103
) {
67
- first = 0 ;
68
104
return 0 ;
69
105
}
70
106
@@ -96,7 +132,7 @@ extern "C" JNIEXPORT jint Java_io_github_brucewind_softcodec_StreamHelper_compr
96
132
ISVCEncoder *en = (ISVCEncoder *) _encoder;
97
133
98
134
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 .
100
136
int result = 0 ;
101
137
int i = 0 ;
102
138
int i_frame_size = 0 ;
@@ -110,34 +146,17 @@ extern "C" JNIEXPORT jint Java_io_github_brucewind_softcodec_StreamHelper_compr
110
146
111
147
112
148
// 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);
139
158
140
- }
159
+ // }
141
160
142
161
143
162
// encode and store ouput bistream
@@ -166,42 +185,66 @@ extern "C" JNIEXPORT jint Java_io_github_brucewind_softcodec_StreamHelper_compr
166
185
}
167
186
return -1 ;
168
187
}
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
-
182
188
if (info.iLayerNum <= 0 ) {
183
189
ALOGE (" something wrong in \" i_frame_size < 0\" ." );
184
190
return -1 ;
185
191
}
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
+
186
206
187
207
/* *
188
208
* 2. The second step:
189
209
* transmit serveral NALUs to RTMP server.
190
210
* Two NAL types : SPS & PPS are very important.
191
211
*/
192
212
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
+ }
197
247
}
198
- else {// TODO
199
-
200
- }
201
-
202
- send_rtmp_video (info.sLayerInfo [i].pBsBuf ,
203
- info.sLayerInfo [i].pNalLengthInByte [0 ],
204
- getSystemTime ()); // into.uiTimeStamp
205
248
ALOGD (" send_rtmp_video() end" );
206
249
207
250
// release buffers.
0 commit comments