I have been resting at home for a while, and I have invited some bosses from small companies and several business departments from Penguin. To be honest, I should be very interested in the past, but now I am not very interested.
I have talked with penguin HR, and people always feel good about themselves. I think the principle can be solved if the salary is higher, in fact, which of the people living in Nanshan do not know the company that is still on the lights at midnight, the company that claims to be off the night city. Maybe the penguin is selling health and life, but the process looks gorgeous.
There is now a sign that Internet companies are moving toward no bottom line when working overtime.
I always thought this was normal. I guess there are not a few people who think about it. It wasn't until I met a foreign colleague who had been around for 9 to 6 every day, even though others had been around for more than 9 o'clock. Once I was puzzled, I directly asked him why he had left so early. As a result, he said it was not surprising that he had to cook at home and had to do housework. I rely on it. The answer is so concise that I was dizzy with my peptide alloy dog brain, and my colleagues who went home to cook every day.
I remember when I picked up my parents from Shenzhen two years ago, my mom was always washing clothes and quilts for me in the previous two weeks, while my dad was wiping and scanning in the house, the old man still keeps saying that I am lazy. I don't know if you have such experiences.
Now let's think about it. Maybe I can't blame myself. I get off work every day at, and I get home at 10 o'clock. I have to go to bed after o'clock. If I have to worry about housework, then I am really a saint-man.
In fact, sometimes doing housework is also a luxury. If you are a foreigner, you can only think about it.
However, it's always right to keep your clothes fresh and clean. Then I thought of a good way to keep my parents around. At least I can change my clothes once a day, even the washing machine is saved.
A friend wants to create a Streaming Media Server for business purposes and asks me if I want to help. I think it's better to give him a pivot because I am idle, but this guy is really lazy, as soon as I helped him, I simply wrote it.
I remember that when I was in thunder, Thunder's streaming media servers were based on rtmp/HLS and were able to adapt to various network environments. But now this application scenario is P-S mode, RTSP is enough.
The current streaming media servers on the market include live555 and Darwin.
Live555 is a select-based RTSP Streaming Media Server developed in C ++.
To be honest, the readability and style of the Code cannot be respected. Comments can be seen everywhere. Take the parsing function as an example:
unsigned j = i+1; while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; // skip over any additional white space for (; (int)j < (int)(reqStrSize-8); ++j) { if ((reqStr[j] == 'r' || reqStr[j] == 'R')&& (reqStr[j+1] == 't' || reqStr[j+1] == 'T')&& (reqStr[j+2] == 's' || reqStr[j+2] == 'S')&& (reqStr[j+3] == 'p' || reqStr[j+3] == 'P')&& reqStr[j+4] == ':' && reqStr[j+5] == '/') { j += 6; if (reqStr[j] == '/') {// This is a "rtsp://" URL; skip over the host:port part that follows:++j;while (j < reqStrSize && reqStr[j] != '/' && reqStr[j] != ' ') ++j; } else {// This is a "rtsp:/" URL; back up to the "/":--j; } i = j; break; } } // Look for the URL suffix (before the following "RTSP/"): parseSucceeded = False; for (unsigned k = i+1; (int)k < (int)(reqStrSize-5); ++k) { if (reqStr[k] == 'R' && reqStr[k+1] == 'T' &&reqStr[k+2] == 'S' && reqStr[k+3] == 'P' && reqStr[k+4] == '/') { while (--k >= i && reqStr[k] == ' ') {} // go back over all spaces before "RTSP/" unsigned k1 = k; while (k1 > i && reqStr[k1] != '/') --k1; // ASSERT: At this point // i: first space or slash after "host" or "host:port" // k: last non-space before "RTSP/" // k1: last slash in the range [i,k] // The URL suffix comes from [k1+1,k] // Copy "resultURLSuffix": unsigned n = 0, k2 = k1+1; if (i <= k) { // There's a slash after "host" or "host:port" if (k - k1 + 1 > resultURLSuffixMaxSize) return False; // there's no room while (k2 <= k) resultURLSuffix[n++] = reqStr[k2++]; } resultURLSuffix[n] = '\0'; // The URL 'pre-suffix' comes from [i+1,k1-1] // Copy "resultURLPreSuffix": n = 0; k2 = i + 1; if (i <= k) { // There's a slash after "host" or "host:port" if (k1 - i > resultURLPreSuffixMaxSize) return False; // there's no room while (k2 <= k1 - 1) resultURLPreSuffix[n++] = reqStr[k2++]; } resultURLPreSuffix[n] = '\0'; decodeURL(resultURLPreSuffix); i = k + 7; // to go past " RTSP/" parseSucceeded = True; break; } }
The main function of this Code is to parse the RTSP header:
When comparing strings, you can convert 'rtsp 'to an integer before comparison.
In addition, from the CPU operation point of view, 25th and 51 rows can be optimized.
Live555 puts events and transactions in the first-line process for processing. The event model is based on the old select model, and the transactions basically have Io. Therefore, when the concurrency reaches a certain level, the server is running Io.
In fact, such a business needs to be separated from events, otherwise it will become a "red pipe ".
However, live555 can indeed complete the RTSP protocol, which is understandable.
It is entirely possible for my Streaming Media Server to surpass live555 in terms of performance. Because it is based on the new efficient event model epoll and a multi-threaded architecture, such a product is still missing in the market. To facilitate your research, I am going to serialize the development process of the server.
If you look at the entire series of blog posts as a table, let's start with an appealer today and the data structure of streaming media requests. You can start with the request to see what parameters will be involved in a request.
struct yumei_rtsp_s{ long long client_ip; int udp_port; yumei_rtsp_media_t *media; yumei_rtsp_track_t *track; };struct yumei_rtsp_req_s{ int version; int req_id; int req_type; long long session_id; char header[ 4 ]; void *media_name; void *track_name; void *req_cmd; void *user_agent; void *transport; void *accept; void *range;};
Business definition and processing functions:
typedef int (*yumei_rtsp_busi_handle )( yumei_rtsp_busi_t *busi );struct yumei_rtsp_busi_s{ void *conn; void *pool; void *rtsp; yumei_rtsp_req_t req; yumei_rtsp_busi_handle handle; };int yumei_rtsp_busi_handle_options( yumei_rtsp_busi_t *busi );int yumei_rtsp_busi_handle_describe( yumei_rtsp_busi_t *busi );int yumei_rtsp_busi_handle_setup( yumei_rtsp_busi_t *busi );int yumei_rtsp_busi_handle_play( yumei_rtsp_busi_t *busi );int yumei_rtsp_busi_handle_pause( yumei_rtsp_busi_t *busi );int yumei_rtsp_busi_handle_teardown( yumei_rtsp_busi_t *busi );int yumei_rtsp_busi_handle_get_parameter( yumei_rtsp_busi_t *busi );int yumei_rtsp_busi_handle_set_parameter( yumei_rtsp_busi_t *busi );
Next, let's look at a simple business function:
int yumei_rtsp_busi_header( yumei_rtsp_busi_t *busi ){ yumei_conn_t *conn; yumei_mem_buf_t *sb; int len; const char* date; conn = busi->conn; sb = conn->send_buf; date = yumei_time_get_current_buf(); len = sprintf( sb->data, rtsp_rsp_header, busi->req_id, date ); sb->pos = len; return YUMEI_RTSP_OK;}int yumei_rtsp_busi_handle_options( yumei_rtsp_busi_t *busi ){ yumei_conn_t *conn; yumei_mem_buf_t *sb; int len, len2; conn = busi->conn; sb = conn->send_buf; yumei_rtsp_busi_header( busi ); len = sb->pos - 1; len2 = strcpy( sb->data + len, rtsp_rsp_options ); sb->pos = len + len2; return YUMEI_RTSP_OK; }
First, at least the code is clear and concise.