mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
refine for bug#66, implements the usage.
This commit is contained in:
parent
0075779d38
commit
3358570be6
5 changed files with 64 additions and 19 deletions
|
@ -37,7 +37,7 @@ gcc srs_h264_raw_publish.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_h
|
|||
|
||||
#define srs_trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n")
|
||||
|
||||
int read_h264_frame(char* data, int size, char** pp, int fps,
|
||||
int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fps,
|
||||
char** frame, int* frame_size, int* dts, int* pts)
|
||||
{
|
||||
char* p = *pp;
|
||||
|
@ -45,8 +45,7 @@ int read_h264_frame(char* data, int size, char** pp, int fps,
|
|||
// @remark, for this demo, to publish h264 raw file to SRS,
|
||||
// we search the h264 frame from the buffer which cached the h264 data.
|
||||
// please get h264 raw data from device, it always a encoded frame.
|
||||
int pnb_start_code = 0;
|
||||
if (!srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) {
|
||||
if (!srs_h264_startswith_annexb(p, size - (p - data), pnb_start_code)) {
|
||||
srs_trace("h264 raw data invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
@ -55,10 +54,10 @@ int read_h264_frame(char* data, int size, char** pp, int fps,
|
|||
// each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0,
|
||||
// for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40)
|
||||
*frame = p;
|
||||
p += pnb_start_code;
|
||||
p += *pnb_start_code;
|
||||
|
||||
for (;p < data + size; p++) {
|
||||
if (srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) {
|
||||
if (srs_h264_startswith_annexb(p, size - (p - data), NULL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +159,10 @@ int main(int argc, char** argv)
|
|||
// @remark, read a frame from file buffer.
|
||||
char* data = NULL;
|
||||
int size = 0;
|
||||
if (read_h264_frame(h264_raw, file_size, &p, fps, &data, &size, &dts, &pts) < 0) {
|
||||
int nb_start_code = 0;
|
||||
if (read_h264_frame(h264_raw, file_size, &p, &nb_start_code, fps,
|
||||
&data, &size, &dts, &pts) < 0
|
||||
) {
|
||||
srs_trace("read a frame from file buffer failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
@ -173,9 +175,9 @@ int main(int argc, char** argv)
|
|||
|
||||
// 5bits, 7.3.1 NAL unit syntax,
|
||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||
u_int8_t nut = (char)data[0] & 0x1f;
|
||||
srs_trace("sent packet: type=%s, time=%d, size=%d, fps=%d, b[0]=%#x(%s)",
|
||||
srs_type2string(SRS_RTMP_TYPE_VIDEO), dts, size, fps, (char)data[0],
|
||||
u_int8_t nut = (char)data[nb_start_code] & 0x1f;
|
||||
srs_trace("sent packet: type=%s, time=%d, size=%d, fps=%d, b[%d]=%#x(%s)",
|
||||
srs_type2string(SRS_RTMP_TYPE_VIDEO), dts, size, fps, nb_start_code, (char)data[nb_start_code],
|
||||
(nut == 7? "SPS":(nut == 8? "PPS":(nut == 5? "I":(nut == 1? "P":"Unknown")))));
|
||||
|
||||
// @remark, when use encode device, it not need to sleep.
|
||||
|
|
|
@ -531,7 +531,7 @@ int SrsAvcAacCodec::avc_demux_annexb_format(SrsStream* stream, SrsCodecSample* s
|
|||
|
||||
// get the last matched NALU
|
||||
while (!stream->empty()) {
|
||||
if (srs_avc_startswith_annexb(stream, &nb_start_code)) {
|
||||
if (srs_avc_startswith_annexb(stream, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -184,6 +184,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_KERNEL_STREAM_INIT 3038
|
||||
#define ERROR_EDGE_VHOST_REMOVED 3039
|
||||
#define ERROR_HLS_AVC_TRY_OTHERS 3040
|
||||
#define ERROR_H264_API_NO_PREFIXED 3041
|
||||
|
||||
/**
|
||||
* whether the error code is an system control error.
|
||||
|
|
|
@ -70,6 +70,10 @@ struct Context
|
|||
SimpleSocketStream* skt;
|
||||
int stream_id;
|
||||
|
||||
// for h264 raw stream,
|
||||
// see: https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521
|
||||
SrsStream raw_stream;
|
||||
|
||||
Context() {
|
||||
rtmp = NULL;
|
||||
skt = NULL;
|
||||
|
@ -995,15 +999,6 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize)
|
|||
|
||||
return any->human_print(pdata, psize);
|
||||
}
|
||||
|
||||
int srs_write_h264_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_int32_t dts, u_int32_t pts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
srs_assert(frames_size > 1);
|
||||
|
||||
srs_assert(rtmp != NULL);
|
||||
Context* context = (Context*)rtmp;
|
||||
|
||||
/*// 5bits, 7.3.1 NAL unit syntax,
|
||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||
|
@ -1051,6 +1046,52 @@ int srs_write_h264_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_
|
|||
*p++ = pp[2];
|
||||
*p++ = pp[1];
|
||||
*p++ = pp[0];*/
|
||||
|
||||
int srs_write_h264_raw_frame(Context* context, char* frame, int frame_size, u_int32_t dts, u_int32_t pts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srs_write_h264_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_int32_t dts, u_int32_t pts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
srs_assert(frames_size > 1);
|
||||
|
||||
srs_assert(rtmp != NULL);
|
||||
Context* context = (Context*)rtmp;
|
||||
|
||||
if ((ret = context->raw_stream.initialize(frames, frames_size)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send each frame.
|
||||
while (!context->raw_stream.empty()) {
|
||||
// each frame must prefixed by annexb format.
|
||||
// about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
|
||||
int pnb_start_code = 0;
|
||||
if (!srs_avc_startswith_annexb(&context->raw_stream, &pnb_start_code)) {
|
||||
return ERROR_H264_API_NO_PREFIXED;
|
||||
}
|
||||
int start = context->raw_stream.pos() + pnb_start_code;
|
||||
|
||||
// find the last frame prefixed by annexb format.
|
||||
context->raw_stream.skip(pnb_start_code);
|
||||
while (!context->raw_stream.empty()) {
|
||||
if (srs_avc_startswith_annexb(&context->raw_stream, NULL)) {
|
||||
break;
|
||||
}
|
||||
context->raw_stream.skip(1);
|
||||
}
|
||||
int size = context->raw_stream.pos() - start;
|
||||
|
||||
// send out the frame.
|
||||
char* frame = context->raw_stream.data() + start;
|
||||
if ((ret = srs_write_h264_raw_frame(context, frame, size, dts, pts)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -342,6 +342,7 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize);
|
|||
* frames can be one or more than one frame,
|
||||
* each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0,
|
||||
* for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40)
|
||||
* about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
|
||||
* @paam frames_size the size of h264 raw data.
|
||||
* assert frames_size > 1, at least has 1 bytes header.
|
||||
* @param dts the dts of h.264 raw data.
|
||||
|
|
Loading…
Reference in a new issue