正在显示
2 个修改的文件
包含
503 行增加
和
503 行删除
| @@ -858,117 +858,6 @@ int srs_version_revision() | @@ -858,117 +858,6 @@ int srs_version_revision() | ||
| 858 | return VERSION_REVISION; | 858 | return VERSION_REVISION; |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | -int64_t srs_utils_get_time_ms() | ||
| 862 | -{ | ||
| 863 | - srs_update_system_time_ms(); | ||
| 864 | - return srs_get_system_time_ms(); | ||
| 865 | -} | ||
| 866 | - | ||
| 867 | -int64_t srs_utils_get_send_bytes(srs_rtmp_t rtmp) | ||
| 868 | -{ | ||
| 869 | - srs_assert(rtmp != NULL); | ||
| 870 | - Context* context = (Context*)rtmp; | ||
| 871 | - return context->rtmp->get_send_bytes(); | ||
| 872 | -} | ||
| 873 | - | ||
| 874 | -int64_t srs_utils_get_recv_bytes(srs_rtmp_t rtmp) | ||
| 875 | -{ | ||
| 876 | - srs_assert(rtmp != NULL); | ||
| 877 | - Context* context = (Context*)rtmp; | ||
| 878 | - return context->rtmp->get_recv_bytes(); | ||
| 879 | -} | ||
| 880 | - | ||
| 881 | -int srs_utils_parse_timestamp( | ||
| 882 | - u_int32_t time, char type, char* data, int size, | ||
| 883 | - u_int32_t* ppts | ||
| 884 | -) { | ||
| 885 | - int ret = ERROR_SUCCESS; | ||
| 886 | - | ||
| 887 | - if (type != SRS_RTMP_TYPE_VIDEO) { | ||
| 888 | - *ppts = time; | ||
| 889 | - return ret; | ||
| 890 | - } | ||
| 891 | - | ||
| 892 | - if (!SrsFlvCodec::video_is_h264(data, size)) { | ||
| 893 | - return ERROR_FLV_INVALID_VIDEO_TAG; | ||
| 894 | - } | ||
| 895 | - | ||
| 896 | - if (SrsFlvCodec::video_is_sequence_header(data, size)) { | ||
| 897 | - *ppts = time; | ||
| 898 | - return ret; | ||
| 899 | - } | ||
| 900 | - | ||
| 901 | - // 1bytes, frame type and codec id. | ||
| 902 | - // 1bytes, avc packet type. | ||
| 903 | - // 3bytes, cts, composition time, | ||
| 904 | - // pts = dts + cts, or | ||
| 905 | - // cts = pts - dts. | ||
| 906 | - if (size < 5) { | ||
| 907 | - return ERROR_FLV_INVALID_VIDEO_TAG; | ||
| 908 | - } | ||
| 909 | - | ||
| 910 | - u_int32_t cts = 0; | ||
| 911 | - char* p = data + 2; | ||
| 912 | - char* pp = (char*)&cts; | ||
| 913 | - pp[2] = *p++; | ||
| 914 | - pp[1] = *p++; | ||
| 915 | - pp[0] = *p++; | ||
| 916 | - | ||
| 917 | - *ppts = time + cts; | ||
| 918 | - | ||
| 919 | - return ret; | ||
| 920 | -} | ||
| 921 | - | ||
| 922 | -char srs_utils_get_flv_video_codec_id(char* data, int size) | ||
| 923 | -{ | ||
| 924 | - if (size < 1) { | ||
| 925 | - return 0; | ||
| 926 | - } | ||
| 927 | - | ||
| 928 | - char codec_id = data[0]; | ||
| 929 | - codec_id = codec_id & 0x0F; | ||
| 930 | - | ||
| 931 | - return codec_id; | ||
| 932 | -} | ||
| 933 | - | ||
| 934 | -char srs_utils_get_flv_video_avc_packet_type(char* data, int size) | ||
| 935 | -{ | ||
| 936 | - if (size < 2) { | ||
| 937 | - return -1; | ||
| 938 | - } | ||
| 939 | - | ||
| 940 | - if (!SrsFlvCodec::video_is_h264(data, size)) { | ||
| 941 | - return -1; | ||
| 942 | - } | ||
| 943 | - | ||
| 944 | - u_int8_t avc_packet_type = data[1]; | ||
| 945 | - | ||
| 946 | - if (avc_packet_type > 2) { | ||
| 947 | - return -1; | ||
| 948 | - } | ||
| 949 | - | ||
| 950 | - return avc_packet_type; | ||
| 951 | -} | ||
| 952 | - | ||
| 953 | -char srs_utils_get_flv_video_frame_type(char* data, int size) | ||
| 954 | -{ | ||
| 955 | - if (size < 1) { | ||
| 956 | - return -1; | ||
| 957 | - } | ||
| 958 | - | ||
| 959 | - if (!SrsFlvCodec::video_is_h264(data, size)) { | ||
| 960 | - return -1; | ||
| 961 | - } | ||
| 962 | - | ||
| 963 | - u_int8_t frame_type = data[0]; | ||
| 964 | - frame_type = (frame_type >> 4) & 0x0f; | ||
| 965 | - if (frame_type < 1 || frame_type > 5) { | ||
| 966 | - return -1; | ||
| 967 | - } | ||
| 968 | - | ||
| 969 | - return frame_type; | ||
| 970 | -} | ||
| 971 | - | ||
| 972 | struct FlvContext | 861 | struct FlvContext |
| 973 | { | 862 | { |
| 974 | SrsFileReader reader; | 863 | SrsFileReader reader; |
| @@ -1432,264 +1321,101 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) | @@ -1432,264 +1321,101 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) | ||
| 1432 | obj->append(any); | 1321 | obj->append(any); |
| 1433 | } | 1322 | } |
| 1434 | 1323 | ||
| 1435 | -char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize) | ||
| 1436 | -{ | ||
| 1437 | - if (!amf0) { | ||
| 1438 | - return NULL; | 1324 | +/** |
| 1325 | +* write audio raw frame to SRS. | ||
| 1326 | +*/ | ||
| 1327 | +int srs_audio_write_raw_frame(srs_rtmp_t rtmp, | ||
| 1328 | + char sound_format, char sound_rate, char sound_size, char sound_type, | ||
| 1329 | + char aac_packet_type, char* frame, int frame_size, u_int32_t timestamp | ||
| 1330 | +) { | ||
| 1331 | + Context* context = (Context*)rtmp; | ||
| 1332 | + srs_assert(context); | ||
| 1333 | + | ||
| 1334 | + // TODO: FIXME: for aac, must send the sequence header first. | ||
| 1335 | + | ||
| 1336 | + // for audio frame, there is 1 or 2 bytes header: | ||
| 1337 | + // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType | ||
| 1338 | + // 1bytes, AACPacketType for SoundFormat == 10 | ||
| 1339 | + int size = frame_size + 1; | ||
| 1340 | + if (aac_packet_type == SrsCodecAudioAAC) { | ||
| 1341 | + size += 1; | ||
| 1439 | } | 1342 | } |
| 1343 | + char* data = new char[size]; | ||
| 1344 | + char* p = data; | ||
| 1440 | 1345 | ||
| 1441 | - SrsAmf0Any* any = (SrsAmf0Any*)amf0; | 1346 | + u_int8_t audio_header = sound_type & 0x01; |
| 1347 | + audio_header |= (sound_size << 1) & 0x02; | ||
| 1348 | + audio_header |= (sound_rate << 2) & 0x0c; | ||
| 1349 | + audio_header |= (sound_format << 4) & 0xf0; | ||
| 1442 | 1350 | ||
| 1443 | - return any->human_print(pdata, psize); | ||
| 1444 | -} | ||
| 1445 | - | ||
| 1446 | -const char* srs_human_flv_tag_type2string(char type) | ||
| 1447 | -{ | ||
| 1448 | - static const char* audio = "Audio"; | ||
| 1449 | - static const char* video = "Video"; | ||
| 1450 | - static const char* data = "Data"; | ||
| 1451 | - static const char* unknown = "Unknown"; | 1351 | + *p++ = audio_header; |
| 1452 | 1352 | ||
| 1453 | - switch (type) { | ||
| 1454 | - case SRS_RTMP_TYPE_AUDIO: return audio; | ||
| 1455 | - case SRS_RTMP_TYPE_VIDEO: return video; | ||
| 1456 | - case SRS_RTMP_TYPE_SCRIPT: return data; | ||
| 1457 | - default: return unknown; | 1353 | + if (aac_packet_type == SrsCodecAudioAAC) { |
| 1354 | + *p++ = aac_packet_type; | ||
| 1458 | } | 1355 | } |
| 1459 | 1356 | ||
| 1460 | - return unknown; | 1357 | + memcpy(p, frame, frame_size); |
| 1358 | + | ||
| 1359 | + return srs_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size); | ||
| 1461 | } | 1360 | } |
| 1462 | 1361 | ||
| 1463 | -const char* srs_human_flv_video_codec_id2string(char codec_id) | ||
| 1464 | -{ | ||
| 1465 | - static const char* h263 = "H.263"; | ||
| 1466 | - static const char* screen = "Screen"; | ||
| 1467 | - static const char* vp6 = "VP6"; | ||
| 1468 | - static const char* vp6_alpha = "VP6Alpha"; | ||
| 1469 | - static const char* screen2 = "Screen2"; | ||
| 1470 | - static const char* h264 = "H.264"; | ||
| 1471 | - static const char* unknown = "Unknown"; | 1362 | +/** |
| 1363 | +* write h264 packet, with rtmp header. | ||
| 1364 | +* @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame. | ||
| 1365 | +* @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU. | ||
| 1366 | +* @param h264_raw_data the h.264 raw data, user must free it. | ||
| 1367 | +*/ | ||
| 1368 | +int __srs_write_h264_packet(Context* context, | ||
| 1369 | + int8_t frame_type, int8_t avc_packet_type, | ||
| 1370 | + char* h264_raw_data, int h264_raw_size, u_int32_t dts, u_int32_t pts | ||
| 1371 | +) { | ||
| 1372 | + // the timestamp in rtmp message header is dts. | ||
| 1373 | + u_int32_t timestamp = dts; | ||
| 1472 | 1374 | ||
| 1473 | - switch (codec_id) { | ||
| 1474 | - case 2: return h263; | ||
| 1475 | - case 3: return screen; | ||
| 1476 | - case 4: return vp6; | ||
| 1477 | - case 5: return vp6_alpha; | ||
| 1478 | - case 6: return screen2; | ||
| 1479 | - case 7: return h264; | ||
| 1480 | - default: return unknown; | ||
| 1481 | - } | 1375 | + // for h264 in RTMP video payload, there is 5bytes header: |
| 1376 | + // 1bytes, FrameType | CodecID | ||
| 1377 | + // 1bytes, AVCPacketType | ||
| 1378 | + // 3bytes, CompositionTime, the cts. | ||
| 1379 | + // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 | ||
| 1380 | + int size = h264_raw_size + 5; | ||
| 1381 | + char* data = new char[size]; | ||
| 1382 | + char* p = data; | ||
| 1482 | 1383 | ||
| 1483 | - return unknown; | ||
| 1484 | -} | 1384 | + // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 |
| 1385 | + // Frame Type, Type of video frame. | ||
| 1386 | + // CodecID, Codec Identifier. | ||
| 1387 | + // set the rtmp header | ||
| 1388 | + *p++ = (frame_type << 4) | SrsCodecVideoAVC; | ||
| 1389 | + | ||
| 1390 | + // AVCPacketType | ||
| 1391 | + *p++ = avc_packet_type; | ||
| 1485 | 1392 | ||
| 1486 | -const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type) | ||
| 1487 | -{ | ||
| 1488 | - static const char* sps_pps = "SpsPps"; | ||
| 1489 | - static const char* nalu = "Nalu"; | ||
| 1490 | - static const char* sps_pps_end = "SpsPpsEnd"; | ||
| 1491 | - static const char* unknown = "Unknown"; | 1393 | + // CompositionTime |
| 1394 | + // pts = dts + cts, or | ||
| 1395 | + // cts = pts - dts. | ||
| 1396 | + // where cts is the header in rtmp video packet payload header. | ||
| 1397 | + u_int32_t cts = pts - dts; | ||
| 1398 | + char* pp = (char*)&cts; | ||
| 1399 | + *p++ = pp[2]; | ||
| 1400 | + *p++ = pp[1]; | ||
| 1401 | + *p++ = pp[0]; | ||
| 1492 | 1402 | ||
| 1493 | - switch (avc_packet_type) { | ||
| 1494 | - case 0: return sps_pps; | ||
| 1495 | - case 1: return nalu; | ||
| 1496 | - case 2: return sps_pps_end; | ||
| 1497 | - default: return unknown; | ||
| 1498 | - } | 1403 | + // h.264 raw data. |
| 1404 | + memcpy(p, h264_raw_data, h264_raw_size); | ||
| 1499 | 1405 | ||
| 1500 | - return unknown; | 1406 | + return srs_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, data, size); |
| 1501 | } | 1407 | } |
| 1502 | 1408 | ||
| 1503 | -const char* srs_human_flv_video_frame_type2string(char frame_type) | 1409 | +/** |
| 1410 | +* write the h264 sps/pps in context over RTMP. | ||
| 1411 | +*/ | ||
| 1412 | +int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts) | ||
| 1504 | { | 1413 | { |
| 1505 | - static const char* keyframe = "I"; | ||
| 1506 | - static const char* interframe = "P/B"; | ||
| 1507 | - static const char* disposable_interframe = "DI"; | ||
| 1508 | - static const char* generated_keyframe = "GI"; | ||
| 1509 | - static const char* video_infoframe = "VI"; | ||
| 1510 | - static const char* unknown = "Unknown"; | 1414 | + int ret = ERROR_SUCCESS; |
| 1511 | 1415 | ||
| 1512 | - switch (frame_type) { | ||
| 1513 | - case 1: return keyframe; | ||
| 1514 | - case 2: return interframe; | ||
| 1515 | - case 3: return disposable_interframe; | ||
| 1516 | - case 4: return generated_keyframe; | ||
| 1517 | - case 5: return video_infoframe; | ||
| 1518 | - default: return unknown; | ||
| 1519 | - } | ||
| 1520 | - | ||
| 1521 | - return unknown; | ||
| 1522 | -} | ||
| 1523 | - | ||
| 1524 | -int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size) | ||
| 1525 | -{ | ||
| 1526 | - int ret = ERROR_SUCCESS; | ||
| 1527 | - | ||
| 1528 | - u_int32_t pts; | ||
| 1529 | - if (srs_utils_parse_timestamp(timestamp, type, data, size, &pts) != 0) { | ||
| 1530 | - return ret; | ||
| 1531 | - } | ||
| 1532 | - | ||
| 1533 | - if (type == SRS_RTMP_TYPE_VIDEO) { | ||
| 1534 | - srs_human_trace("Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s)", | ||
| 1535 | - srs_human_flv_tag_type2string(type), timestamp, pts, size, | ||
| 1536 | - srs_human_flv_video_codec_id2string(srs_utils_get_flv_video_codec_id(data, size)), | ||
| 1537 | - srs_human_flv_video_avc_packet_type2string(srs_utils_get_flv_video_avc_packet_type(data, size)), | ||
| 1538 | - srs_human_flv_video_frame_type2string(srs_utils_get_flv_video_frame_type(data, size)) | ||
| 1539 | - ); | ||
| 1540 | - } else if (type == SRS_RTMP_TYPE_AUDIO) { | ||
| 1541 | - srs_human_trace("Audio packet type=%s, dts=%d, pts=%d, size=%d", | ||
| 1542 | - srs_human_flv_tag_type2string(type), timestamp, pts, size); | ||
| 1543 | - } else if (type == SRS_RTMP_TYPE_SCRIPT) { | ||
| 1544 | - srs_human_verbose("Data packet type=%s, time=%d, size=%d", | ||
| 1545 | - srs_human_flv_tag_type2string(type), timestamp, size); | ||
| 1546 | - int nparsed = 0; | ||
| 1547 | - while (nparsed < size) { | ||
| 1548 | - int nb_parsed_this = 0; | ||
| 1549 | - srs_amf0_t amf0 = srs_amf0_parse(data + nparsed, size - nparsed, &nb_parsed_this); | ||
| 1550 | - if (amf0 == NULL) { | ||
| 1551 | - break; | ||
| 1552 | - } | ||
| 1553 | - | ||
| 1554 | - nparsed += nb_parsed_this; | ||
| 1555 | - | ||
| 1556 | - char* amf0_str = NULL; | ||
| 1557 | - srs_human_raw("%s", srs_human_amf0_print(amf0, &amf0_str, NULL)); | ||
| 1558 | - srs_amf0_free_bytes(amf0_str); | ||
| 1559 | - } | ||
| 1560 | - } else { | ||
| 1561 | - srs_human_trace("Unknown packet type=%s, dts=%d, pts=%d, size=%d", | ||
| 1562 | - srs_human_flv_tag_type2string(type), timestamp, pts, size); | ||
| 1563 | - } | ||
| 1564 | - | ||
| 1565 | - return ret; | ||
| 1566 | -} | ||
| 1567 | - | ||
| 1568 | -const char* srs_human_format_time() | ||
| 1569 | -{ | ||
| 1570 | - struct timeval tv; | ||
| 1571 | - static char buf[23]; | ||
| 1572 | - | ||
| 1573 | - memset(buf, 0, sizeof(buf)); | ||
| 1574 | - | ||
| 1575 | - // clock time | ||
| 1576 | - if (gettimeofday(&tv, NULL) == -1) { | ||
| 1577 | - return buf; | ||
| 1578 | - } | ||
| 1579 | - | ||
| 1580 | - // to calendar time | ||
| 1581 | - struct tm* tm; | ||
| 1582 | - if ((tm = localtime((const time_t*)&tv.tv_sec)) == NULL) { | ||
| 1583 | - return buf; | ||
| 1584 | - } | ||
| 1585 | - | ||
| 1586 | - snprintf(buf, sizeof(buf), | ||
| 1587 | - "%d-%02d-%02d %02d:%02d:%02d.%03d", | ||
| 1588 | - 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, | ||
| 1589 | - tm->tm_hour, tm->tm_min, tm->tm_sec, | ||
| 1590 | - (int)(tv.tv_usec / 1000)); | ||
| 1591 | - | ||
| 1592 | - // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 | ||
| 1593 | - buf[sizeof(buf) - 1] = 0; | ||
| 1594 | - | ||
| 1595 | - return buf; | ||
| 1596 | -} | ||
| 1597 | - | ||
| 1598 | -/** | ||
| 1599 | -* write audio raw frame to SRS. | ||
| 1600 | -*/ | ||
| 1601 | -int srs_audio_write_raw_frame(srs_rtmp_t rtmp, | ||
| 1602 | - char sound_format, char sound_rate, char sound_size, char sound_type, | ||
| 1603 | - char aac_packet_type, char* frame, int frame_size, u_int32_t timestamp | ||
| 1604 | -) { | ||
| 1605 | - Context* context = (Context*)rtmp; | ||
| 1606 | - srs_assert(context); | ||
| 1607 | - | ||
| 1608 | - // TODO: FIXME: for aac, must send the sequence header first. | ||
| 1609 | - | ||
| 1610 | - // for audio frame, there is 1 or 2 bytes header: | ||
| 1611 | - // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType | ||
| 1612 | - // 1bytes, AACPacketType for SoundFormat == 10 | ||
| 1613 | - int size = frame_size + 1; | ||
| 1614 | - if (aac_packet_type == SrsCodecAudioAAC) { | ||
| 1615 | - size += 1; | ||
| 1616 | - } | ||
| 1617 | - char* data = new char[size]; | ||
| 1618 | - char* p = data; | ||
| 1619 | - | ||
| 1620 | - u_int8_t audio_header = sound_type & 0x01; | ||
| 1621 | - audio_header |= (sound_size << 1) & 0x02; | ||
| 1622 | - audio_header |= (sound_rate << 2) & 0x0c; | ||
| 1623 | - audio_header |= (sound_format << 4) & 0xf0; | ||
| 1624 | - | ||
| 1625 | - *p++ = audio_header; | ||
| 1626 | - | ||
| 1627 | - if (aac_packet_type == SrsCodecAudioAAC) { | ||
| 1628 | - *p++ = aac_packet_type; | ||
| 1629 | - } | ||
| 1630 | - | ||
| 1631 | - memcpy(p, frame, frame_size); | ||
| 1632 | - | ||
| 1633 | - return srs_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size); | ||
| 1634 | -} | ||
| 1635 | - | ||
| 1636 | -/** | ||
| 1637 | -* write h264 packet, with rtmp header. | ||
| 1638 | -* @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame. | ||
| 1639 | -* @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU. | ||
| 1640 | -* @param h264_raw_data the h.264 raw data, user must free it. | ||
| 1641 | -*/ | ||
| 1642 | -int __srs_write_h264_packet(Context* context, | ||
| 1643 | - int8_t frame_type, int8_t avc_packet_type, | ||
| 1644 | - char* h264_raw_data, int h264_raw_size, u_int32_t dts, u_int32_t pts | ||
| 1645 | -) { | ||
| 1646 | - // the timestamp in rtmp message header is dts. | ||
| 1647 | - u_int32_t timestamp = dts; | ||
| 1648 | - | ||
| 1649 | - // for h264 in RTMP video payload, there is 5bytes header: | ||
| 1650 | - // 1bytes, FrameType | CodecID | ||
| 1651 | - // 1bytes, AVCPacketType | ||
| 1652 | - // 3bytes, CompositionTime, the cts. | ||
| 1653 | - // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 | ||
| 1654 | - int size = h264_raw_size + 5; | ||
| 1655 | - char* data = new char[size]; | ||
| 1656 | - char* p = data; | ||
| 1657 | - | ||
| 1658 | - // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 | ||
| 1659 | - // Frame Type, Type of video frame. | ||
| 1660 | - // CodecID, Codec Identifier. | ||
| 1661 | - // set the rtmp header | ||
| 1662 | - *p++ = (frame_type << 4) | SrsCodecVideoAVC; | ||
| 1663 | - | ||
| 1664 | - // AVCPacketType | ||
| 1665 | - *p++ = avc_packet_type; | ||
| 1666 | - | ||
| 1667 | - // CompositionTime | ||
| 1668 | - // pts = dts + cts, or | ||
| 1669 | - // cts = pts - dts. | ||
| 1670 | - // where cts is the header in rtmp video packet payload header. | ||
| 1671 | - u_int32_t cts = pts - dts; | ||
| 1672 | - char* pp = (char*)&cts; | ||
| 1673 | - *p++ = pp[2]; | ||
| 1674 | - *p++ = pp[1]; | ||
| 1675 | - *p++ = pp[0]; | ||
| 1676 | - | ||
| 1677 | - // h.264 raw data. | ||
| 1678 | - memcpy(p, h264_raw_data, h264_raw_size); | ||
| 1679 | - | ||
| 1680 | - return srs_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, data, size); | ||
| 1681 | -} | ||
| 1682 | - | ||
| 1683 | -/** | ||
| 1684 | -* write the h264 sps/pps in context over RTMP. | ||
| 1685 | -*/ | ||
| 1686 | -int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts) | ||
| 1687 | -{ | ||
| 1688 | - int ret = ERROR_SUCCESS; | ||
| 1689 | - | ||
| 1690 | - // only send when both sps and pps changed. | ||
| 1691 | - if (!context->h264_sps_changed || !context->h264_pps_changed) { | ||
| 1692 | - return ret; | 1416 | + // only send when both sps and pps changed. |
| 1417 | + if (!context->h264_sps_changed || !context->h264_pps_changed) { | ||
| 1418 | + return ret; | ||
| 1693 | } | 1419 | } |
| 1694 | 1420 | ||
| 1695 | // 5bytes sps/pps header: | 1421 | // 5bytes sps/pps header: |
| @@ -1986,6 +1712,280 @@ int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_ | @@ -1986,6 +1712,280 @@ int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_ | ||
| 1986 | return srs_avc_startswith_annexb(&stream, pnb_start_code); | 1712 | return srs_avc_startswith_annexb(&stream, pnb_start_code); |
| 1987 | } | 1713 | } |
| 1988 | 1714 | ||
| 1715 | +int64_t srs_utils_get_time_ms() | ||
| 1716 | +{ | ||
| 1717 | + srs_update_system_time_ms(); | ||
| 1718 | + return srs_get_system_time_ms(); | ||
| 1719 | +} | ||
| 1720 | + | ||
| 1721 | +int64_t srs_utils_get_send_bytes(srs_rtmp_t rtmp) | ||
| 1722 | +{ | ||
| 1723 | + srs_assert(rtmp != NULL); | ||
| 1724 | + Context* context = (Context*)rtmp; | ||
| 1725 | + return context->rtmp->get_send_bytes(); | ||
| 1726 | +} | ||
| 1727 | + | ||
| 1728 | +int64_t srs_utils_get_recv_bytes(srs_rtmp_t rtmp) | ||
| 1729 | +{ | ||
| 1730 | + srs_assert(rtmp != NULL); | ||
| 1731 | + Context* context = (Context*)rtmp; | ||
| 1732 | + return context->rtmp->get_recv_bytes(); | ||
| 1733 | +} | ||
| 1734 | + | ||
| 1735 | +int srs_utils_parse_timestamp( | ||
| 1736 | + u_int32_t time, char type, char* data, int size, | ||
| 1737 | + u_int32_t* ppts | ||
| 1738 | +) { | ||
| 1739 | + int ret = ERROR_SUCCESS; | ||
| 1740 | + | ||
| 1741 | + if (type != SRS_RTMP_TYPE_VIDEO) { | ||
| 1742 | + *ppts = time; | ||
| 1743 | + return ret; | ||
| 1744 | + } | ||
| 1745 | + | ||
| 1746 | + if (!SrsFlvCodec::video_is_h264(data, size)) { | ||
| 1747 | + return ERROR_FLV_INVALID_VIDEO_TAG; | ||
| 1748 | + } | ||
| 1749 | + | ||
| 1750 | + if (SrsFlvCodec::video_is_sequence_header(data, size)) { | ||
| 1751 | + *ppts = time; | ||
| 1752 | + return ret; | ||
| 1753 | + } | ||
| 1754 | + | ||
| 1755 | + // 1bytes, frame type and codec id. | ||
| 1756 | + // 1bytes, avc packet type. | ||
| 1757 | + // 3bytes, cts, composition time, | ||
| 1758 | + // pts = dts + cts, or | ||
| 1759 | + // cts = pts - dts. | ||
| 1760 | + if (size < 5) { | ||
| 1761 | + return ERROR_FLV_INVALID_VIDEO_TAG; | ||
| 1762 | + } | ||
| 1763 | + | ||
| 1764 | + u_int32_t cts = 0; | ||
| 1765 | + char* p = data + 2; | ||
| 1766 | + char* pp = (char*)&cts; | ||
| 1767 | + pp[2] = *p++; | ||
| 1768 | + pp[1] = *p++; | ||
| 1769 | + pp[0] = *p++; | ||
| 1770 | + | ||
| 1771 | + *ppts = time + cts; | ||
| 1772 | + | ||
| 1773 | + return ret; | ||
| 1774 | +} | ||
| 1775 | + | ||
| 1776 | +char srs_utils_get_flv_video_codec_id(char* data, int size) | ||
| 1777 | +{ | ||
| 1778 | + if (size < 1) { | ||
| 1779 | + return 0; | ||
| 1780 | + } | ||
| 1781 | + | ||
| 1782 | + char codec_id = data[0]; | ||
| 1783 | + codec_id = codec_id & 0x0F; | ||
| 1784 | + | ||
| 1785 | + return codec_id; | ||
| 1786 | +} | ||
| 1787 | + | ||
| 1788 | +char srs_utils_get_flv_video_avc_packet_type(char* data, int size) | ||
| 1789 | +{ | ||
| 1790 | + if (size < 2) { | ||
| 1791 | + return -1; | ||
| 1792 | + } | ||
| 1793 | + | ||
| 1794 | + if (!SrsFlvCodec::video_is_h264(data, size)) { | ||
| 1795 | + return -1; | ||
| 1796 | + } | ||
| 1797 | + | ||
| 1798 | + u_int8_t avc_packet_type = data[1]; | ||
| 1799 | + | ||
| 1800 | + if (avc_packet_type > 2) { | ||
| 1801 | + return -1; | ||
| 1802 | + } | ||
| 1803 | + | ||
| 1804 | + return avc_packet_type; | ||
| 1805 | +} | ||
| 1806 | + | ||
| 1807 | +char srs_utils_get_flv_video_frame_type(char* data, int size) | ||
| 1808 | +{ | ||
| 1809 | + if (size < 1) { | ||
| 1810 | + return -1; | ||
| 1811 | + } | ||
| 1812 | + | ||
| 1813 | + if (!SrsFlvCodec::video_is_h264(data, size)) { | ||
| 1814 | + return -1; | ||
| 1815 | + } | ||
| 1816 | + | ||
| 1817 | + u_int8_t frame_type = data[0]; | ||
| 1818 | + frame_type = (frame_type >> 4) & 0x0f; | ||
| 1819 | + if (frame_type < 1 || frame_type > 5) { | ||
| 1820 | + return -1; | ||
| 1821 | + } | ||
| 1822 | + | ||
| 1823 | + return frame_type; | ||
| 1824 | +} | ||
| 1825 | + | ||
| 1826 | +char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize) | ||
| 1827 | +{ | ||
| 1828 | + if (!amf0) { | ||
| 1829 | + return NULL; | ||
| 1830 | + } | ||
| 1831 | + | ||
| 1832 | + SrsAmf0Any* any = (SrsAmf0Any*)amf0; | ||
| 1833 | + | ||
| 1834 | + return any->human_print(pdata, psize); | ||
| 1835 | +} | ||
| 1836 | + | ||
| 1837 | +const char* srs_human_flv_tag_type2string(char type) | ||
| 1838 | +{ | ||
| 1839 | + static const char* audio = "Audio"; | ||
| 1840 | + static const char* video = "Video"; | ||
| 1841 | + static const char* data = "Data"; | ||
| 1842 | + static const char* unknown = "Unknown"; | ||
| 1843 | + | ||
| 1844 | + switch (type) { | ||
| 1845 | + case SRS_RTMP_TYPE_AUDIO: return audio; | ||
| 1846 | + case SRS_RTMP_TYPE_VIDEO: return video; | ||
| 1847 | + case SRS_RTMP_TYPE_SCRIPT: return data; | ||
| 1848 | + default: return unknown; | ||
| 1849 | + } | ||
| 1850 | + | ||
| 1851 | + return unknown; | ||
| 1852 | +} | ||
| 1853 | + | ||
| 1854 | +const char* srs_human_flv_video_codec_id2string(char codec_id) | ||
| 1855 | +{ | ||
| 1856 | + static const char* h263 = "H.263"; | ||
| 1857 | + static const char* screen = "Screen"; | ||
| 1858 | + static const char* vp6 = "VP6"; | ||
| 1859 | + static const char* vp6_alpha = "VP6Alpha"; | ||
| 1860 | + static const char* screen2 = "Screen2"; | ||
| 1861 | + static const char* h264 = "H.264"; | ||
| 1862 | + static const char* unknown = "Unknown"; | ||
| 1863 | + | ||
| 1864 | + switch (codec_id) { | ||
| 1865 | + case 2: return h263; | ||
| 1866 | + case 3: return screen; | ||
| 1867 | + case 4: return vp6; | ||
| 1868 | + case 5: return vp6_alpha; | ||
| 1869 | + case 6: return screen2; | ||
| 1870 | + case 7: return h264; | ||
| 1871 | + default: return unknown; | ||
| 1872 | + } | ||
| 1873 | + | ||
| 1874 | + return unknown; | ||
| 1875 | +} | ||
| 1876 | + | ||
| 1877 | +const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type) | ||
| 1878 | +{ | ||
| 1879 | + static const char* sps_pps = "SpsPps"; | ||
| 1880 | + static const char* nalu = "Nalu"; | ||
| 1881 | + static const char* sps_pps_end = "SpsPpsEnd"; | ||
| 1882 | + static const char* unknown = "Unknown"; | ||
| 1883 | + | ||
| 1884 | + switch (avc_packet_type) { | ||
| 1885 | + case 0: return sps_pps; | ||
| 1886 | + case 1: return nalu; | ||
| 1887 | + case 2: return sps_pps_end; | ||
| 1888 | + default: return unknown; | ||
| 1889 | + } | ||
| 1890 | + | ||
| 1891 | + return unknown; | ||
| 1892 | +} | ||
| 1893 | + | ||
| 1894 | +const char* srs_human_flv_video_frame_type2string(char frame_type) | ||
| 1895 | +{ | ||
| 1896 | + static const char* keyframe = "I"; | ||
| 1897 | + static const char* interframe = "P/B"; | ||
| 1898 | + static const char* disposable_interframe = "DI"; | ||
| 1899 | + static const char* generated_keyframe = "GI"; | ||
| 1900 | + static const char* video_infoframe = "VI"; | ||
| 1901 | + static const char* unknown = "Unknown"; | ||
| 1902 | + | ||
| 1903 | + switch (frame_type) { | ||
| 1904 | + case 1: return keyframe; | ||
| 1905 | + case 2: return interframe; | ||
| 1906 | + case 3: return disposable_interframe; | ||
| 1907 | + case 4: return generated_keyframe; | ||
| 1908 | + case 5: return video_infoframe; | ||
| 1909 | + default: return unknown; | ||
| 1910 | + } | ||
| 1911 | + | ||
| 1912 | + return unknown; | ||
| 1913 | +} | ||
| 1914 | + | ||
| 1915 | +int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size) | ||
| 1916 | +{ | ||
| 1917 | + int ret = ERROR_SUCCESS; | ||
| 1918 | + | ||
| 1919 | + u_int32_t pts; | ||
| 1920 | + if (srs_utils_parse_timestamp(timestamp, type, data, size, &pts) != 0) { | ||
| 1921 | + return ret; | ||
| 1922 | + } | ||
| 1923 | + | ||
| 1924 | + if (type == SRS_RTMP_TYPE_VIDEO) { | ||
| 1925 | + srs_human_trace("Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s)", | ||
| 1926 | + srs_human_flv_tag_type2string(type), timestamp, pts, size, | ||
| 1927 | + srs_human_flv_video_codec_id2string(srs_utils_get_flv_video_codec_id(data, size)), | ||
| 1928 | + srs_human_flv_video_avc_packet_type2string(srs_utils_get_flv_video_avc_packet_type(data, size)), | ||
| 1929 | + srs_human_flv_video_frame_type2string(srs_utils_get_flv_video_frame_type(data, size)) | ||
| 1930 | + ); | ||
| 1931 | + } else if (type == SRS_RTMP_TYPE_AUDIO) { | ||
| 1932 | + srs_human_trace("Audio packet type=%s, dts=%d, pts=%d, size=%d", | ||
| 1933 | + srs_human_flv_tag_type2string(type), timestamp, pts, size); | ||
| 1934 | + } else if (type == SRS_RTMP_TYPE_SCRIPT) { | ||
| 1935 | + srs_human_verbose("Data packet type=%s, time=%d, size=%d", | ||
| 1936 | + srs_human_flv_tag_type2string(type), timestamp, size); | ||
| 1937 | + int nparsed = 0; | ||
| 1938 | + while (nparsed < size) { | ||
| 1939 | + int nb_parsed_this = 0; | ||
| 1940 | + srs_amf0_t amf0 = srs_amf0_parse(data + nparsed, size - nparsed, &nb_parsed_this); | ||
| 1941 | + if (amf0 == NULL) { | ||
| 1942 | + break; | ||
| 1943 | + } | ||
| 1944 | + | ||
| 1945 | + nparsed += nb_parsed_this; | ||
| 1946 | + | ||
| 1947 | + char* amf0_str = NULL; | ||
| 1948 | + srs_human_raw("%s", srs_human_amf0_print(amf0, &amf0_str, NULL)); | ||
| 1949 | + srs_amf0_free_bytes(amf0_str); | ||
| 1950 | + } | ||
| 1951 | + } else { | ||
| 1952 | + srs_human_trace("Unknown packet type=%s, dts=%d, pts=%d, size=%d", | ||
| 1953 | + srs_human_flv_tag_type2string(type), timestamp, pts, size); | ||
| 1954 | + } | ||
| 1955 | + | ||
| 1956 | + return ret; | ||
| 1957 | +} | ||
| 1958 | + | ||
| 1959 | +const char* srs_human_format_time() | ||
| 1960 | +{ | ||
| 1961 | + struct timeval tv; | ||
| 1962 | + static char buf[23]; | ||
| 1963 | + | ||
| 1964 | + memset(buf, 0, sizeof(buf)); | ||
| 1965 | + | ||
| 1966 | + // clock time | ||
| 1967 | + if (gettimeofday(&tv, NULL) == -1) { | ||
| 1968 | + return buf; | ||
| 1969 | + } | ||
| 1970 | + | ||
| 1971 | + // to calendar time | ||
| 1972 | + struct tm* tm; | ||
| 1973 | + if ((tm = localtime((const time_t*)&tv.tv_sec)) == NULL) { | ||
| 1974 | + return buf; | ||
| 1975 | + } | ||
| 1976 | + | ||
| 1977 | + snprintf(buf, sizeof(buf), | ||
| 1978 | + "%d-%02d-%02d %02d:%02d:%02d.%03d", | ||
| 1979 | + 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, | ||
| 1980 | + tm->tm_hour, tm->tm_min, tm->tm_sec, | ||
| 1981 | + (int)(tv.tv_usec / 1000)); | ||
| 1982 | + | ||
| 1983 | + // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 | ||
| 1984 | + buf[sizeof(buf) - 1] = 0; | ||
| 1985 | + | ||
| 1986 | + return buf; | ||
| 1987 | +} | ||
| 1988 | + | ||
| 1989 | #ifdef __cplusplus | 1989 | #ifdef __cplusplus |
| 1990 | } | 1990 | } |
| 1991 | #endif | 1991 | #endif |
| @@ -265,83 +265,6 @@ extern int srs_version_revision(); | @@ -265,83 +265,6 @@ extern int srs_version_revision(); | ||
| 265 | 265 | ||
| 266 | /************************************************************* | 266 | /************************************************************* |
| 267 | ************************************************************** | 267 | ************************************************************** |
| 268 | -* utilities | ||
| 269 | -************************************************************** | ||
| 270 | -*************************************************************/ | ||
| 271 | -/** | ||
| 272 | -* get the current system time in ms. | ||
| 273 | -* use gettimeofday() to get system time. | ||
| 274 | -*/ | ||
| 275 | -extern int64_t srs_utils_get_time_ms(); | ||
| 276 | - | ||
| 277 | -/** | ||
| 278 | -* get the send bytes. | ||
| 279 | -*/ | ||
| 280 | -extern int64_t srs_utils_get_send_bytes(srs_rtmp_t rtmp); | ||
| 281 | - | ||
| 282 | -/** | ||
| 283 | -* get the recv bytes. | ||
| 284 | -*/ | ||
| 285 | -extern int64_t srs_utils_get_recv_bytes(srs_rtmp_t rtmp); | ||
| 286 | - | ||
| 287 | -/** | ||
| 288 | -* parse the dts and pts by time in header and data in tag, | ||
| 289 | -* or to parse the RTMP packet by srs_read_packet(). | ||
| 290 | -* | ||
| 291 | -* @param time, the timestamp of tag, read by srs_flv_read_tag_header(). | ||
| 292 | -* @param type, the type of tag, read by srs_flv_read_tag_header(). | ||
| 293 | -* @param data, the data of tag, read by srs_flv_read_tag_data(). | ||
| 294 | -* @param size, the size of tag, read by srs_flv_read_tag_header(). | ||
| 295 | -* @param ppts, output the pts in ms, | ||
| 296 | -* | ||
| 297 | -* @return 0, success; otherswise, failed. | ||
| 298 | -* @remark, the dts always equals to @param time. | ||
| 299 | -* @remark, the pts=dts for audio or data. | ||
| 300 | -* @remark, video only support h.264. | ||
| 301 | -*/ | ||
| 302 | -extern int srs_utils_parse_timestamp( | ||
| 303 | - u_int32_t time, char type, char* data, int size, | ||
| 304 | - u_int32_t* ppts | ||
| 305 | -); | ||
| 306 | - | ||
| 307 | -/** | ||
| 308 | -* get the CodecID of video tag. | ||
| 309 | -* Codec Identifier. The following values are defined: | ||
| 310 | -* 2 = Sorenson H.263 | ||
| 311 | -* 3 = Screen video | ||
| 312 | -* 4 = On2 VP6 | ||
| 313 | -* 5 = On2 VP6 with alpha channel | ||
| 314 | -* 6 = Screen video version 2 | ||
| 315 | -* 7 = AVC | ||
| 316 | -* @return the code id. 0 for error. | ||
| 317 | -*/ | ||
| 318 | -extern char srs_utils_get_flv_video_codec_id(char* data, int size); | ||
| 319 | - | ||
| 320 | -/** | ||
| 321 | -* get the AVCPacketType of video tag. | ||
| 322 | -* The following values are defined: | ||
| 323 | -* 0 = AVC sequence header | ||
| 324 | -* 1 = AVC NALU | ||
| 325 | -* 2 = AVC end of sequence (lower level NALU sequence ender is | ||
| 326 | -* not required or supported) | ||
| 327 | -* @return the avc packet type. -1(0xff) for error. | ||
| 328 | -*/ | ||
| 329 | -extern char srs_utils_get_flv_video_avc_packet_type(char* data, int size); | ||
| 330 | - | ||
| 331 | -/** | ||
| 332 | -* get the FrameType of video tag. | ||
| 333 | -* Type of video frame. The following values are defined: | ||
| 334 | -* 1 = key frame (for AVC, a seekable frame) | ||
| 335 | -* 2 = inter frame (for AVC, a non-seekable frame) | ||
| 336 | -* 3 = disposable inter frame (H.263 only) | ||
| 337 | -* 4 = generated key frame (reserved for server use only) | ||
| 338 | -* 5 = video info/command frame | ||
| 339 | -* @return the frame type. 0 for error. | ||
| 340 | -*/ | ||
| 341 | -extern char srs_utils_get_flv_video_frame_type(char* data, int size); | ||
| 342 | - | ||
| 343 | -/************************************************************* | ||
| 344 | -************************************************************** | ||
| 345 | * flv codec | 268 | * flv codec |
| 346 | * @example /trunk/research/librtmp/srs_flv_injecter.c | 269 | * @example /trunk/research/librtmp/srs_flv_injecter.c |
| 347 | * @example /trunk/research/librtmp/srs_flv_parser.c | 270 | * @example /trunk/research/librtmp/srs_flv_parser.c |
| @@ -500,80 +423,6 @@ extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value); | @@ -500,80 +423,6 @@ extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value); | ||
| 500 | 423 | ||
| 501 | /************************************************************* | 424 | /************************************************************* |
| 502 | ************************************************************** | 425 | ************************************************************** |
| 503 | -* human readable print. | ||
| 504 | -************************************************************** | ||
| 505 | -*************************************************************/ | ||
| 506 | -/** | ||
| 507 | -* human readable print | ||
| 508 | -* @param pdata, output the heap data, NULL to ignore. | ||
| 509 | -* user must use srs_amf0_free_bytes to free it. | ||
| 510 | -* @return return the *pdata for print. NULL to ignore. | ||
| 511 | -*/ | ||
| 512 | -extern char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize); | ||
| 513 | -/** | ||
| 514 | -* convert the flv tag type to string. | ||
| 515 | -* SRS_RTMP_TYPE_AUDIO to "Audio" | ||
| 516 | -* SRS_RTMP_TYPE_VIDEO to "Video" | ||
| 517 | -* SRS_RTMP_TYPE_SCRIPT to "Data" | ||
| 518 | -* otherwise, "Unknown" | ||
| 519 | -* @remark user never free the return char*, | ||
| 520 | -* it's static shared const string. | ||
| 521 | -*/ | ||
| 522 | -extern const char* srs_human_flv_tag_type2string(char type); | ||
| 523 | - | ||
| 524 | -/** | ||
| 525 | -* get the codec id string. | ||
| 526 | -* H.263 = Sorenson H.263 | ||
| 527 | -* Screen = Screen video | ||
| 528 | -* VP6 = On2 VP6 | ||
| 529 | -* VP6Alpha = On2 VP6 with alpha channel | ||
| 530 | -* Screen2 = Screen video version 2 | ||
| 531 | -* H.264 = AVC | ||
| 532 | -* otherwise, "Unknown" | ||
| 533 | -* @remark user never free the return char*, | ||
| 534 | -* it's static shared const string. | ||
| 535 | -*/ | ||
| 536 | -extern const char* srs_human_flv_video_codec_id2string(char codec_id); | ||
| 537 | - | ||
| 538 | -/** | ||
| 539 | -* get the avc packet type string. | ||
| 540 | -* SpsPps = AVC sequence header | ||
| 541 | -* Nalu = AVC NALU | ||
| 542 | -* SpsPpsEnd = AVC end of sequence | ||
| 543 | -* otherwise, "Unknown" | ||
| 544 | -* @remark user never free the return char*, | ||
| 545 | -* it's static shared const string. | ||
| 546 | -*/ | ||
| 547 | -extern const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type); | ||
| 548 | - | ||
| 549 | -/** | ||
| 550 | -* get the frame type string. | ||
| 551 | -* I = key frame (for AVC, a seekable frame) | ||
| 552 | -* P/B = inter frame (for AVC, a non-seekable frame) | ||
| 553 | -* DI = disposable inter frame (H.263 only) | ||
| 554 | -* GI = generated key frame (reserved for server use only) | ||
| 555 | -* VI = video info/command frame | ||
| 556 | -* otherwise, "Unknown" | ||
| 557 | -* @remark user never free the return char*, | ||
| 558 | -* it's static shared const string. | ||
| 559 | -*/ | ||
| 560 | -extern const char* srs_human_flv_video_frame_type2string(char frame_type); | ||
| 561 | - | ||
| 562 | -/** | ||
| 563 | -* print the rtmp packet, use srs_human_trace/srs_human_verbose for packet, | ||
| 564 | -* and use srs_human_raw for script data body. | ||
| 565 | -* @return an error code for parse the timetstamp to dts and pts. | ||
| 566 | -*/ | ||
| 567 | -extern int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size); | ||
| 568 | - | ||
| 569 | -// log to console, for use srs-librtmp application. | ||
| 570 | -extern const char* srs_human_format_time(); | ||
| 571 | -#define srs_human_trace(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n") | ||
| 572 | -#define srs_human_verbose(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n") | ||
| 573 | -#define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__) | ||
| 574 | - | ||
| 575 | -/************************************************************* | ||
| 576 | -************************************************************** | ||
| 577 | * audio raw codec | 426 | * audio raw codec |
| 578 | ************************************************************** | 427 | ************************************************************** |
| 579 | *************************************************************/ | 428 | *************************************************************/ |
| @@ -735,6 +584,157 @@ extern int srs_h264_startswith_annexb( | @@ -735,6 +584,157 @@ extern int srs_h264_startswith_annexb( | ||
| 735 | int* pnb_start_code | 584 | int* pnb_start_code |
| 736 | ); | 585 | ); |
| 737 | 586 | ||
| 587 | +/************************************************************* | ||
| 588 | +************************************************************** | ||
| 589 | +* utilities | ||
| 590 | +************************************************************** | ||
| 591 | +*************************************************************/ | ||
| 592 | +/** | ||
| 593 | +* get the current system time in ms. | ||
| 594 | +* use gettimeofday() to get system time. | ||
| 595 | +*/ | ||
| 596 | +extern int64_t srs_utils_get_time_ms(); | ||
| 597 | + | ||
| 598 | +/** | ||
| 599 | +* get the send bytes. | ||
| 600 | +*/ | ||
| 601 | +extern int64_t srs_utils_get_send_bytes(srs_rtmp_t rtmp); | ||
| 602 | + | ||
| 603 | +/** | ||
| 604 | +* get the recv bytes. | ||
| 605 | +*/ | ||
| 606 | +extern int64_t srs_utils_get_recv_bytes(srs_rtmp_t rtmp); | ||
| 607 | + | ||
| 608 | +/** | ||
| 609 | +* parse the dts and pts by time in header and data in tag, | ||
| 610 | +* or to parse the RTMP packet by srs_read_packet(). | ||
| 611 | +* | ||
| 612 | +* @param time, the timestamp of tag, read by srs_flv_read_tag_header(). | ||
| 613 | +* @param type, the type of tag, read by srs_flv_read_tag_header(). | ||
| 614 | +* @param data, the data of tag, read by srs_flv_read_tag_data(). | ||
| 615 | +* @param size, the size of tag, read by srs_flv_read_tag_header(). | ||
| 616 | +* @param ppts, output the pts in ms, | ||
| 617 | +* | ||
| 618 | +* @return 0, success; otherswise, failed. | ||
| 619 | +* @remark, the dts always equals to @param time. | ||
| 620 | +* @remark, the pts=dts for audio or data. | ||
| 621 | +* @remark, video only support h.264. | ||
| 622 | +*/ | ||
| 623 | +extern int srs_utils_parse_timestamp( | ||
| 624 | + u_int32_t time, char type, char* data, int size, | ||
| 625 | + u_int32_t* ppts | ||
| 626 | +); | ||
| 627 | + | ||
| 628 | +/** | ||
| 629 | +* get the CodecID of video tag. | ||
| 630 | +* Codec Identifier. The following values are defined: | ||
| 631 | +* 2 = Sorenson H.263 | ||
| 632 | +* 3 = Screen video | ||
| 633 | +* 4 = On2 VP6 | ||
| 634 | +* 5 = On2 VP6 with alpha channel | ||
| 635 | +* 6 = Screen video version 2 | ||
| 636 | +* 7 = AVC | ||
| 637 | +* @return the code id. 0 for error. | ||
| 638 | +*/ | ||
| 639 | +extern char srs_utils_get_flv_video_codec_id(char* data, int size); | ||
| 640 | + | ||
| 641 | +/** | ||
| 642 | +* get the AVCPacketType of video tag. | ||
| 643 | +* The following values are defined: | ||
| 644 | +* 0 = AVC sequence header | ||
| 645 | +* 1 = AVC NALU | ||
| 646 | +* 2 = AVC end of sequence (lower level NALU sequence ender is | ||
| 647 | +* not required or supported) | ||
| 648 | +* @return the avc packet type. -1(0xff) for error. | ||
| 649 | +*/ | ||
| 650 | +extern char srs_utils_get_flv_video_avc_packet_type(char* data, int size); | ||
| 651 | + | ||
| 652 | +/** | ||
| 653 | +* get the FrameType of video tag. | ||
| 654 | +* Type of video frame. The following values are defined: | ||
| 655 | +* 1 = key frame (for AVC, a seekable frame) | ||
| 656 | +* 2 = inter frame (for AVC, a non-seekable frame) | ||
| 657 | +* 3 = disposable inter frame (H.263 only) | ||
| 658 | +* 4 = generated key frame (reserved for server use only) | ||
| 659 | +* 5 = video info/command frame | ||
| 660 | +* @return the frame type. 0 for error. | ||
| 661 | +*/ | ||
| 662 | +extern char srs_utils_get_flv_video_frame_type(char* data, int size); | ||
| 663 | + | ||
| 664 | +/************************************************************* | ||
| 665 | +************************************************************** | ||
| 666 | +* human readable print. | ||
| 667 | +************************************************************** | ||
| 668 | +*************************************************************/ | ||
| 669 | +/** | ||
| 670 | +* human readable print | ||
| 671 | +* @param pdata, output the heap data, NULL to ignore. | ||
| 672 | +* user must use srs_amf0_free_bytes to free it. | ||
| 673 | +* @return return the *pdata for print. NULL to ignore. | ||
| 674 | +*/ | ||
| 675 | +extern char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize); | ||
| 676 | +/** | ||
| 677 | +* convert the flv tag type to string. | ||
| 678 | +* SRS_RTMP_TYPE_AUDIO to "Audio" | ||
| 679 | +* SRS_RTMP_TYPE_VIDEO to "Video" | ||
| 680 | +* SRS_RTMP_TYPE_SCRIPT to "Data" | ||
| 681 | +* otherwise, "Unknown" | ||
| 682 | +* @remark user never free the return char*, | ||
| 683 | +* it's static shared const string. | ||
| 684 | +*/ | ||
| 685 | +extern const char* srs_human_flv_tag_type2string(char type); | ||
| 686 | + | ||
| 687 | +/** | ||
| 688 | +* get the codec id string. | ||
| 689 | +* H.263 = Sorenson H.263 | ||
| 690 | +* Screen = Screen video | ||
| 691 | +* VP6 = On2 VP6 | ||
| 692 | +* VP6Alpha = On2 VP6 with alpha channel | ||
| 693 | +* Screen2 = Screen video version 2 | ||
| 694 | +* H.264 = AVC | ||
| 695 | +* otherwise, "Unknown" | ||
| 696 | +* @remark user never free the return char*, | ||
| 697 | +* it's static shared const string. | ||
| 698 | +*/ | ||
| 699 | +extern const char* srs_human_flv_video_codec_id2string(char codec_id); | ||
| 700 | + | ||
| 701 | +/** | ||
| 702 | +* get the avc packet type string. | ||
| 703 | +* SpsPps = AVC sequence header | ||
| 704 | +* Nalu = AVC NALU | ||
| 705 | +* SpsPpsEnd = AVC end of sequence | ||
| 706 | +* otherwise, "Unknown" | ||
| 707 | +* @remark user never free the return char*, | ||
| 708 | +* it's static shared const string. | ||
| 709 | +*/ | ||
| 710 | +extern const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type); | ||
| 711 | + | ||
| 712 | +/** | ||
| 713 | +* get the frame type string. | ||
| 714 | +* I = key frame (for AVC, a seekable frame) | ||
| 715 | +* P/B = inter frame (for AVC, a non-seekable frame) | ||
| 716 | +* DI = disposable inter frame (H.263 only) | ||
| 717 | +* GI = generated key frame (reserved for server use only) | ||
| 718 | +* VI = video info/command frame | ||
| 719 | +* otherwise, "Unknown" | ||
| 720 | +* @remark user never free the return char*, | ||
| 721 | +* it's static shared const string. | ||
| 722 | +*/ | ||
| 723 | +extern const char* srs_human_flv_video_frame_type2string(char frame_type); | ||
| 724 | + | ||
| 725 | +/** | ||
| 726 | +* print the rtmp packet, use srs_human_trace/srs_human_verbose for packet, | ||
| 727 | +* and use srs_human_raw for script data body. | ||
| 728 | +* @return an error code for parse the timetstamp to dts and pts. | ||
| 729 | +*/ | ||
| 730 | +extern int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size); | ||
| 731 | + | ||
| 732 | +// log to console, for use srs-librtmp application. | ||
| 733 | +extern const char* srs_human_format_time(); | ||
| 734 | +#define srs_human_trace(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n") | ||
| 735 | +#define srs_human_verbose(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n") | ||
| 736 | +#define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__) | ||
| 737 | + | ||
| 738 | #ifdef __cplusplus | 738 | #ifdef __cplusplus |
| 739 | } | 739 | } |
| 740 | #endif | 740 | #endif |
-
请 注册 或 登录 后发表评论