Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2015-03-08 15:33:08 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
04f3f2a8f8315809bf52d154f6f6c0af6bbf3816
04f3f2a8
1 parent
8bf60895
for #316, add codec info to stream.
隐藏空白字符变更
内嵌
并排对比
正在显示
8 个修改的文件
包含
286 行增加
和
50 行删除
trunk/src/app/srs_app_json.hpp
trunk/src/app/srs_app_rtmp_conn.cpp
trunk/src/app/srs_app_source.cpp
trunk/src/app/srs_app_statistic.cpp
trunk/src/app/srs_app_statistic.hpp
trunk/src/kernel/srs_kernel_codec.cpp
trunk/src/kernel/srs_kernel_codec.hpp
trunk/src/kernel/srs_kernel_ts.cpp
trunk/src/app/srs_app_json.hpp
查看文件 @
04f3f2a
...
...
@@ -217,6 +217,7 @@ that is:
#define __SRS_JFIELD_STR(k, v) "\"" << k << "\":\"" << v << "\""
#define __SRS_JFIELD_ORG(k, v) "\"" << k << "\":" << std::dec << v
#define __SRS_JFIELD_BOOL(k, v) __SRS_JFIELD_ORG(k, (v? "true":"false"))
#define __SRS_JFIELD_NULL(k) "\"" << k << "\":null"
#define __SRS_JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret
#define __SRS_JFIELD_CONT ","
#define __SRS_JOBJECT_END "}"
...
...
trunk/src/app/srs_app_rtmp_conn.cpp
查看文件 @
04f3f2a
...
...
@@ -202,7 +202,7 @@ int SrsRtmpConn::do_cycle()
ret
=
service_cycle
();
http_hooks_on_close
();
SrsStatistic
*
stat
=
SrsStatistic
::
instance
();
stat
->
on_
close
(
_srs_context
->
get_id
());
stat
->
on_
disconnect
(
_srs_context
->
get_id
());
return
ret
;
}
...
...
trunk/src/app/srs_app_source.cpp
查看文件 @
04f3f2a
...
...
@@ -42,6 +42,7 @@ using namespace std;
#include <srs_kernel_utility.hpp>
#include <srs_kernel_codec.hpp>
#include <srs_rtmp_msg_array.hpp>
#include <srs_app_statistic.hpp>
#define CONST_MAX_JITTER_MS 500
#define DEFAULT_FRAME_TIME_MS 40
...
...
@@ -1373,6 +1374,7 @@ int SrsSource::on_audio(SrsCommonMessage* __audio)
// cache the sequence header of aac, or first packet of mp3.
// for example, the mp3 is used for hls to write the "right" audio codec.
// TODO: FIXME: to refine the stream info system.
bool
is_aac_sequence_header
=
SrsFlvCodec
::
audio_is_sequence_header
(
msg
.
payload
,
msg
.
size
);
if
(
is_aac_sequence_header
||
!
cache_sh_audio
)
{
srs_freep
(
cache_sh_audio
);
...
...
@@ -1392,6 +1394,13 @@ int SrsSource::on_audio(SrsCommonMessage* __audio)
static
int
flv_sample_sizes
[]
=
{
8
,
16
,
0
};
static
int
flv_sound_types
[]
=
{
1
,
2
,
0
};
// when got audio stream info.
SrsStatistic
*
stat
=
SrsStatistic
::
instance
();
if
((
ret
=
stat
->
on_audio_info
(
_req
,
SrsCodecAudioAAC
,
sample
.
sound_rate
,
sample
.
sound_type
,
codec
.
aac_profile
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_trace
(
"%dB audio sh, "
"codec(%d, profile=%d, %dchannels, %dkbps, %dHZ), "
"flv(%dbits, %dchannels, %dHZ)"
,
...
...
@@ -1515,6 +1524,12 @@ int SrsSource::on_video(SrsCommonMessage* __video)
return
ret
;
}
// when got video stream info.
SrsStatistic
*
stat
=
SrsStatistic
::
instance
();
if
((
ret
=
stat
->
on_video_info
(
_req
,
SrsCodecVideoAVC
,
codec
.
avc_profile
,
codec
.
avc_level
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_trace
(
"%dB video sh, "
"codec(%d, profile=%d, level=%d, %dx%d, %dkbps, %dfps, %ds)"
,
msg
.
size
,
codec
.
video_codec_id
,
...
...
trunk/src/app/srs_app_statistic.cpp
查看文件 @
04f3f2a
...
...
@@ -50,12 +50,29 @@ SrsStatisticStream::SrsStatisticStream()
{
id
=
__srs_generate_id
();
vhost
=
NULL
;
has_video
=
false
;
vcodec
=
SrsCodecVideoReserved
;
avc_profile
=
0
;
avc_level
=
0
;
has_audio
=
false
;
acodec
=
SrsCodecAudioReserved1
;
asample_rate
=
SrsCodecAudioSampleRateReserved
;
asound_type
=
SrsCodecAudioSoundTypeReserved
;
aac_profile
=
0
;
}
SrsStatisticStream
::~
SrsStatisticStream
()
{
}
void
SrsStatisticStream
::
close
()
{
has_video
=
false
;
has_audio
=
false
;
}
SrsStatistic
*
SrsStatistic
::
_instance
=
new
SrsStatistic
();
SrsStatistic
::
SrsStatistic
()
...
...
@@ -93,34 +110,54 @@ SrsStatistic* SrsStatistic::instance()
return
_instance
;
}
int
SrsStatistic
::
on_client
(
int
id
,
SrsRequest
*
req
)
{
int
SrsStatistic
::
on_video_info
(
SrsRequest
*
req
,
SrsCodecVideo
vcodec
,
u_int8_t
avc_profile
,
u_int8_t
avc_level
)
{
int
ret
=
ERROR_SUCCESS
;
// create vhost if not exists.
SrsStatisticVhost
*
vhost
=
NULL
;
if
(
vhosts
.
find
(
req
->
vhost
)
==
vhosts
.
end
())
{
vhost
=
new
SrsStatisticVhost
();
vhost
->
vhost
=
req
->
vhost
;
vhosts
[
req
->
vhost
]
=
vhost
;
}
else
{
vhost
=
vhosts
[
req
->
vhost
];
}
SrsStatisticVhost
*
vhost
=
create_vhost
(
req
);
SrsStatisticStream
*
stream
=
create_stream
(
vhost
,
req
);
stream
->
has_video
=
true
;
stream
->
vcodec
=
vcodec
;
stream
->
avc_profile
=
avc_profile
;
stream
->
avc_level
=
avc_level
;
// the url to identify the stream.
std
::
string
url
=
req
->
get_stream_url
();
return
ret
;
}
int
SrsStatistic
::
on_audio_info
(
SrsRequest
*
req
,
SrsCodecAudio
acodec
,
SrsCodecAudioSampleRate
asample_rate
,
SrsCodecAudioSoundType
asound_type
,
u_int8_t
aac_profile
)
{
int
ret
=
ERROR_SUCCESS
;
// create stream if not exists.
SrsStatisticStream
*
stream
=
NULL
;
if
(
streams
.
find
(
url
)
==
streams
.
end
())
{
stream
=
new
SrsStatisticStream
();
stream
->
vhost
=
vhost
;
stream
->
stream
=
req
->
stream
;
stream
->
url
=
url
;
streams
[
url
]
=
stream
;
}
else
{
stream
=
streams
[
url
];
}
SrsStatisticVhost
*
vhost
=
create_vhost
(
req
);
SrsStatisticStream
*
stream
=
create_stream
(
vhost
,
req
);
stream
->
has_audio
=
true
;
stream
->
acodec
=
acodec
;
stream
->
asample_rate
=
asample_rate
;
stream
->
asound_type
=
asound_type
;
stream
->
aac_profile
=
aac_profile
;
return
ret
;
}
void
SrsStatistic
::
on_stream_close
(
SrsRequest
*
req
)
{
SrsStatisticVhost
*
vhost
=
create_vhost
(
req
);
SrsStatisticStream
*
stream
=
create_stream
(
vhost
,
req
);
stream
->
close
();
}
int
SrsStatistic
::
on_client
(
int
id
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
SrsStatisticVhost
*
vhost
=
create_vhost
(
req
);
SrsStatisticStream
*
stream
=
create_stream
(
vhost
,
req
);
// create client if not exists
SrsStatisticClient
*
client
=
NULL
;
...
...
@@ -135,7 +172,7 @@ int SrsStatistic::on_client(int id, SrsRequest* req)
return
ret
;
}
void
SrsStatistic
::
on_
close
(
int
id
)
void
SrsStatistic
::
on_
disconnect
(
int
id
)
{
std
::
map
<
int
,
SrsStatisticClient
*>::
iterator
it
;
it
=
clients
.
find
(
id
);
...
...
@@ -198,10 +235,74 @@ int SrsStatistic::dumps_streams(stringstream& ss)
<<
__SRS_JFIELD_ORG
(
"id"
,
stream
->
id
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"name"
,
stream
->
stream
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"vhost"
,
stream
->
vhost
->
id
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"clients"
,
client_num
)
<<
__SRS_JOBJECT_END
;
<<
__SRS_JFIELD_ORG
(
"clients"
,
client_num
)
<<
__SRS_JFIELD_CONT
;
if
(
!
stream
->
has_video
)
{
ss
<<
__SRS_JFIELD_NULL
(
"video"
)
<<
__SRS_JFIELD_CONT
;
}
else
{
ss
<<
__SRS_JFIELD_NAME
(
"video"
)
<<
__SRS_JOBJECT_START
<<
__SRS_JFIELD_STR
(
"codec"
,
srs_codec_video2str
(
stream
->
vcodec
))
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"profile"
,
(
int
)
stream
->
avc_profile
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"level"
,
(
int
)
stream
->
avc_level
)
<<
__SRS_JOBJECT_END
<<
__SRS_JFIELD_CONT
;
}
if
(
!
stream
->
has_audio
)
{
ss
<<
__SRS_JFIELD_NULL
(
"audio"
);
}
else
{
ss
<<
__SRS_JFIELD_NAME
(
"audio"
)
<<
__SRS_JOBJECT_START
<<
__SRS_JFIELD_STR
(
"codec"
,
srs_codec_audio2str
(
stream
->
acodec
))
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"sample_rate"
,
(
int
)
flv_sample_rates
[
stream
->
asample_rate
])
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"channel"
,
(
int
)
stream
->
asound_type
+
1
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"profile"
,
srs_codec_aac_profile2str
(
stream
->
aac_profile
))
<<
__SRS_JOBJECT_END
;
}
ss
<<
__SRS_JOBJECT_END
;
}
ss
<<
__SRS_JARRAY_END
;
return
ret
;
}
SrsStatisticVhost
*
SrsStatistic
::
create_vhost
(
SrsRequest
*
req
)
{
SrsStatisticVhost
*
vhost
=
NULL
;
// create vhost if not exists.
if
(
vhosts
.
find
(
req
->
vhost
)
==
vhosts
.
end
())
{
vhost
=
new
SrsStatisticVhost
();
vhost
->
vhost
=
req
->
vhost
;
vhosts
[
req
->
vhost
]
=
vhost
;
return
vhost
;
}
vhost
=
vhosts
[
req
->
vhost
];
return
vhost
;
}
SrsStatisticStream
*
SrsStatistic
::
create_stream
(
SrsStatisticVhost
*
vhost
,
SrsRequest
*
req
)
{
std
::
string
url
=
req
->
get_stream_url
();
SrsStatisticStream
*
stream
=
NULL
;
// create stream if not exists.
if
(
streams
.
find
(
url
)
==
streams
.
end
())
{
stream
=
new
SrsStatisticStream
();
stream
->
vhost
=
vhost
;
stream
->
stream
=
req
->
stream
;
stream
->
url
=
url
;
streams
[
url
]
=
stream
;
return
stream
;
}
stream
=
streams
[
url
];
return
stream
;
}
...
...
trunk/src/app/srs_app_statistic.hpp
查看文件 @
04f3f2a
...
...
@@ -33,6 +33,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <map>
#include <string>
#include <srs_kernel_codec.hpp>
class
SrsRequest
;
struct
SrsStatisticVhost
...
...
@@ -54,8 +56,32 @@ public:
std
::
string
stream
;
std
::
string
url
;
public
:
bool
has_video
;
SrsCodecVideo
vcodec
;
// profile_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
u_int8_t
avc_profile
;
// level_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
u_int8_t
avc_level
;
public
:
bool
has_audio
;
SrsCodecAudio
acodec
;
SrsCodecAudioSampleRate
asample_rate
;
SrsCodecAudioSoundType
asound_type
;
/**
* audio specified
* audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33,
* 1.5.1.1 Audio object type definition, page 23,
* in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf.
*/
u_int8_t
aac_profile
;
public
:
SrsStatisticStream
();
virtual
~
SrsStatisticStream
();
public
:
/**
* close the stream.
*/
virtual
void
close
();
};
struct
SrsStatisticClient
...
...
@@ -73,7 +99,7 @@ private:
int64_t
_server_id
;
// key: vhost name, value: vhost object.
std
::
map
<
std
::
string
,
SrsStatisticVhost
*>
vhosts
;
// key: stream
name
, value: stream object.
// key: stream
url
, value: stream object.
std
::
map
<
std
::
string
,
SrsStatisticStream
*>
streams
;
// key: client id, value: stream object.
std
::
map
<
int
,
SrsStatisticClient
*>
clients
;
...
...
@@ -84,15 +110,33 @@ public:
static
SrsStatistic
*
instance
();
public
:
/**
* when got video info for stream.
*/
virtual
int
on_video_info
(
SrsRequest
*
req
,
SrsCodecVideo
vcodec
,
u_int8_t
avc_profile
,
u_int8_t
avc_level
);
/**
* when got audio info for stream.
*/
virtual
int
on_audio_info
(
SrsRequest
*
req
,
SrsCodecAudio
acodec
,
SrsCodecAudioSampleRate
asample_rate
,
SrsCodecAudioSoundType
asound_type
,
u_int8_t
aac_profile
);
/**
* when close stream.
*/
virtual
void
on_stream_close
(
SrsRequest
*
req
);
public
:
/**
* when got a client to publish/play stream,
* @param id, the client srs id.
* @param req, the client request object.
*/
virtual
int
on_client
(
int
id
,
SrsRequest
*
req
);
/**
* client
close
* client
disconnect
*/
virtual
void
on_
close
(
int
id
);
virtual
void
on_
disconnect
(
int
id
);
public
:
/**
* get the server id, used to identify the server.
...
...
@@ -107,6 +151,9 @@ public:
* dumps the streams to sstream in json.
*/
virtual
int
dumps_streams
(
std
::
stringstream
&
ss
);
private
:
virtual
SrsStatisticVhost
*
create_vhost
(
SrsRequest
*
req
);
virtual
SrsStatisticStream
*
create_stream
(
SrsStatisticVhost
*
vhost
,
SrsRequest
*
req
);
};
#endif
...
...
trunk/src/kernel/srs_kernel_codec.cpp
查看文件 @
04f3f2a
...
...
@@ -32,6 +32,80 @@ using namespace std;
#include <srs_kernel_stream.hpp>
#include <srs_kernel_utility.hpp>
string
srs_codec_video2str
(
SrsCodecVideo
codec
)
{
switch
(
codec
)
{
case
SrsCodecVideoAVC
:
return
"H264"
;
case
SrsCodecVideoOn2VP6
:
case
SrsCodecVideoOn2VP6WithAlphaChannel
:
return
"H264"
;
case
SrsCodecVideoReserved
:
case
SrsCodecVideoReserved1
:
case
SrsCodecVideoReserved2
:
case
SrsCodecVideoDisabled
:
case
SrsCodecVideoSorensonH263
:
case
SrsCodecVideoScreenVideo
:
case
SrsCodecVideoScreenVideoVersion2
:
default:
return
"Other"
;
}
}
string
srs_codec_audio2str
(
SrsCodecAudio
codec
)
{
switch
(
codec
)
{
case
SrsCodecAudioAAC
:
return
"AAC"
;
case
SrsCodecAudioMP3
:
return
"MP3"
;
case
SrsCodecAudioReserved1
:
case
SrsCodecAudioLinearPCMPlatformEndian
:
case
SrsCodecAudioADPCM
:
case
SrsCodecAudioLinearPCMLittleEndian
:
case
SrsCodecAudioNellymoser16kHzMono
:
case
SrsCodecAudioNellymoser8kHzMono
:
case
SrsCodecAudioNellymoser
:
case
SrsCodecAudioReservedG711AlawLogarithmicPCM
:
case
SrsCodecAudioReservedG711MuLawLogarithmicPCM
:
case
SrsCodecAudioReserved
:
case
SrsCodecAudioSpeex
:
case
SrsCodecAudioReservedMP3_8kHz
:
case
SrsCodecAudioReservedDeviceSpecificSound
:
default:
return
"Other"
;
}
}
string
srs_codec_aac_profile2str
(
u_int8_t
aac_profile
)
{
switch
(
aac_profile
)
{
case
1
:
return
"Main"
;
case
2
:
return
"LC"
;
case
3
:
return
"SSR"
;
default:
return
"Other"
;
}
}
/**
* the public data, event HLS disable, others can use it.
*/
// 0 = 5.5 kHz = 5512 Hz
// 1 = 11 kHz = 11025 Hz
// 2 = 22 kHz = 22050 Hz
// 3 = 44 kHz = 44100 Hz
int
flv_sample_rates
[]
=
{
5512
,
11025
,
22050
,
44100
};
// the sample rates in the codec,
// in the sequence header.
int
aac_sample_rates
[]
=
{
96000
,
88200
,
64000
,
48000
,
44100
,
32000
,
24000
,
22050
,
16000
,
12000
,
11025
,
8000
,
7350
,
0
,
0
,
0
};
SrsFlvCodec
::
SrsFlvCodec
()
{
}
...
...
trunk/src/kernel/srs_kernel_codec.hpp
查看文件 @
04f3f2a
...
...
@@ -110,6 +110,7 @@ enum SrsCodecVideo
SrsCodecVideoScreenVideoVersion2
=
6
,
SrsCodecVideoAVC
=
7
,
};
std
::
string
srs_codec_video2str
(
SrsCodecVideo
codec
);
// SoundFormat UB [4]
// Format of SoundData. The following values are defined:
...
...
@@ -150,6 +151,7 @@ enum SrsCodecAudio
SrsCodecAudioReservedMP3_8kHz
=
14
,
SrsCodecAudioReservedDeviceSpecificSound
=
15
,
};
std
::
string
srs_codec_audio2str
(
SrsCodecAudio
codec
);
/**
* the FLV/RTMP supported audio sample rate.
...
...
@@ -373,6 +375,21 @@ enum SrsAvcPayloadFormat
SrsAvcPayloadFormatIbmf
,
};
// the profile = object_id + 1
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
// Table 1. A.9 C MPEG-2 Audio profiles and MPEG-4 Audio object types
// the valid object type:
// AAC Main(ID == 0)
// AAC LC(ID == 1)
// AAC SSR(ID == 2)
// AAC LTP(ID == 3)
// the valid aac profile:
// Main profile (ID == 1)
// Low Complexity profile (LC) (ID == 2)
// Scalable Sampling Rate profile (SSR) (ID == 3)
// (reserved) (ID == 4)
std
::
string
srs_codec_aac_profile2str
(
u_int8_t
aac_profile
);
/**
* the h264/avc and aac codec, for media stream.
*
...
...
trunk/src/kernel/srs_kernel_ts.cpp
查看文件 @
04f3f2a
...
...
@@ -56,25 +56,6 @@ using namespace std;
#define TS_AUDIO_AAC_PID 0x102
#define TS_AUDIO_MP3_PID 0x103
/**
* the public data, event HLS disable, others can use it.
*/
// 0 = 5.5 kHz = 5512 Hz
// 1 = 11 kHz = 11025 Hz
// 2 = 22 kHz = 22050 Hz
// 3 = 44 kHz = 44100 Hz
int
flv_sample_rates
[]
=
{
5512
,
11025
,
22050
,
44100
};
// the sample rates in the codec,
// in the sequence header.
int
aac_sample_rates
[]
=
{
96000
,
88200
,
64000
,
48000
,
44100
,
32000
,
24000
,
22050
,
16000
,
12000
,
11025
,
8000
,
7350
,
0
,
0
,
0
};
string
srs_ts_stream2string
(
SrsTsStream
stream
)
{
switch
(
stream
)
{
...
...
请
注册
或
登录
后发表评论