正在显示
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 |
-
请 注册 或 登录 后发表评论