ireader / media-server

RTSP/RTP/RTMP/FLV/HLS/MPEG-TS/MPEG-PS/MPEG-DASH/MP4/fMP4/MKV/WebM
MIT License
3.1k stars 1.08k forks source link

ts转hls关键帧的问题 #204

Closed alexliyu7352 closed 2 years ago

alexliyu7352 commented 2 years ago

最近我在开发ts转hls功能时遇到了一些问题. 因为您的hls库, ts转hls需要标注关键帧, 也就是IDR帧.

但是直接使用ts_demuxer_create回调的flags并不会有IDR. 所以只能靠判断NAL来判断是否是IDR帧.

我先使用了下方您的相关代码, 有些网络测试流可以判断出来, 但是遇到了一些测试时就没办法了.

static inline const uint8_t* h264_startcode(const uint8_t *data, size_t bytes)
{
    size_t i;
    for (i = 2; i + 1 < bytes; i++)
    {
        if (0x01 == data[i] && 0x00 == data[i - 1] && 0x00 == data[i - 2])
            return data + i + 1;
    }

    return NULL;
}

static inline uint8_t h264_idr(const uint8_t *data, size_t bytes)
{
    uint8_t naltype;
    const uint8_t *p;

    do
    {
        p = h264_startcode(data, bytes);
        if (p)
        {
            naltype = p[0] & 0x1f;
            // 1: no-IDR slice
            // 2: A-slice
            // 3: B-slice
            // 4: C-slice
            // 5: IDR frame
            if (naltype > 0 && naltype < 6)
            {
                return 5 == naltype ? 1 : 0;
            }

            bytes -= p - data;
            data = p;
        }
    } while (p);

    return 0;
}

static inline int h265_irap(const uint8_t* p, size_t bytes)
{
    size_t i;
    uint8_t type;
    for (i = 2; i + 1 < bytes; i++)
    {
        if (0x01 == p[i] && 0x00 == p[i - 1] && 0x00 == p[i - 2])
        {
            type = (p[i + 1] >> 1) & 0x3f;
            if (type < 32)
                return (16 <= type && type <= 23) ? 1 : 0;
        }
    }

    return 0;
}

后来我又使用了zlm的判断方法

H264_TYPE(v) ((uint8_t)(v) & 0x1F)
auto nal_ptr = (uint8_t *) this->data() + this->prefixSize();
auto type = H264_TYPE(*nal_ptr);

但是仍旧获得的type没有IDR类型的, 但是使用ffprobe获取, 是显示有关键帧存在的.

我网上搜索看到说, h264不能简单的按照nal来判断是否是关键帧.

我应该怎么做才能确切的获取关键帧呢?

alexliyu7352 commented 2 years ago

0 0x000055caf0937702 in bitstream_read_bits ()

(gdb) fr 4

4 0x000055caf0935b07 in h264_parser_input ()

(gdb) x/256b annexb No symbol "annexb" in current context. (gdb) x/256b annexb No symbol "annexb" in current context.

ireader commented 2 years ago

有个可能死循环的问题,更新下avcodec/libh264。

内存泄露无进展。

ireader commented 2 years ago

x/256b annexb annexb 对应h264_parser_input第二个参数,可以直接输入第二个参数内存地址

alexliyu7352 commented 2 years ago

我发现每次出现了死循环就会导致内存一直上升

alexliyu7352 commented 2 years ago

我更新了您的代码了, 现在重新编译发布.

我这没办法用qq阿

alexliyu7352 commented 2 years ago

昨天编译了您新的代码后, 稳定运行到了现在.

没有出现死循环导致的核心被占满, 也没有出现内存的问题.

但是另外一个问题就是mpeg_h264_find_nalu占用的好像有点高.

Samples: 1M of event 'cycles:ppp', Event count (approx.): 205412026064
  Children      Self  Shared Object        Symbol
+   26.21%     0.08%  [kernel]             [k] entry_SYSCALL_64_after_hwframe
+   26.06%     0.89%  [kernel]             [k] do_syscall_64
+   13.54%     5.63%  libc-2.27.so         [.] __memmove_sse2_unaligned_erms
+   11.63%     0.03%  [kernel]             [k] page_fault
+   11.59%     0.02%  [kernel]             [k] do_page_fault
+   11.51%     0.24%  [kernel]             [k] __do_page_fault
+   10.36%     0.18%  [kernel]             [k] handle_mm_fault
+   10.04%     0.59%  [kernel]             [k] __handle_mm_fault
+    9.75%     8.06%  media_server         [.] mpeg_h264_find_nalu
+    9.39%     0.09%  libpthread-2.27.so   [.] __libc_recvfrom
+    9.02%     0.04%  [kernel]             [k] ret_from_intr
+    8.95%     0.05%  [kernel]             [k] do_IRQ
+    8.52%     0.03%  [kernel]             [k] sys_recvfrom
+    8.45%     0.08%  [kernel]             [k] SYSC_recvfrom
+    8.43%     0.14%  [kernel]             [k] __softirqentry_text_start
+    8.17%     0.12%  [kernel]             [k] irq_exit
+    8.17%     0.31%  [kernel]             [k] do_wp_page
+    8.04%     0.01%  [kernel]             [k] sock_recvmsg
+    7.83%     0.07%  [kernel]             [k] inet_recvmsg
+    7.69%     0.24%  [kernel]             [k] tcp_recvmsg
+    7.40%     0.12%  [kernel]             [k] net_rx_action
+    7.23%     0.08%  [kernel]             [k] flush_tlb_mm_range
+    7.02%     0.06%  [kernel]             [k] wp_page_copy
+    6.94%     0.01%  [kernel]             [k] native_flush_tlb_others
+    6.76%     3.83%  [kernel]             [k] smp_call_function_many
+    6.45%     0.03%  [kernel]             [k] ptep_clear_flush
+    6.41%     0.04%  [kernel]             [k] mlx4_en_poll_rx_cq
+    6.27%     0.02%  libpthread-2.27.so   [.] __libc_sendmsg
+    6.12%     0.01%  [kernel]             [k] __sys_sendmsg
+    6.08%     0.01%  [kernel]             [k] sys_sendmsg
+    6.05%     0.04%  [kernel]             [k] ___sys_sendmsg
+    5.83%     0.01%  [kernel]             [k] sock_sendmsg
+    5.79%     0.04%  [kernel]             [k] inet_sendmsg
+    5.74%     0.00%  [kernel]             [k] tcp_sendmsg
+    5.67%     0.16%  [kernel]             [k] tcp_sendmsg_locked
+    5.54%     0.24%  [kernel]             [k] __tcp_transmit_skb
+    5.35%     4.53%  [kernel]             [k] copy_user_generic_string
+    5.04%     0.09%  [kernel]             [k] ip_queue_xmit
+    4.83%     0.02%  [kernel]             [k] ip_local_out
+    4.80%     0.08%  libc-2.27.so         [.] epoll_wait
+    4.75%     0.01%  [kernel]             [k] __netif_receive_skb
+    4.73%     0.16%  [kernel]             [k] __netif_receive_skb_core
+    4.63%     4.00%  media_server         [.] mediakit::splitH264
+    4.58%     0.02%  [kernel]             [k] netif_receive_skb_internal
+    4.55%     0.09%  [kernel]             [k] ip_rcv
+    4.18%     0.05%  [kernel]             [k] sys_epoll_wait
     4.13%     0.63%  [kernel]             [k] mlx4_en_process_rx_cq
+    4.01%     0.01%  [kernel]             [k] tcp_send_ack
+    4.00%     0.03%  [kernel]             [k] __tcp_send_ack.part.39
+    3.94%     0.12%  [kernel]             [k] ep_poll
ireader commented 2 years ago

mpeg_h264_find_nalu用于判断ts/ps帧边界,ts可能确实不需要。

alexliyu7352 commented 2 years ago

如何能安全的去掉呢?直接注释掉么?

alexliyu7352 commented 2 years ago

目前运行到现在仍旧没有出现死循环的问题. 看来应该是解决了

ireader commented 2 years ago

如何能安全的去掉呢?直接注释掉么?

目前没有办法去掉,周末我看看有没有别的方式。

alexliyu7352 commented 2 years ago

好的, 辛苦您了

Chen @.***> 于2022年3月31日周四 12:23写道:

如何能安全的去掉呢?直接注释掉么?

目前没有办法去掉,周末我看看有没有别的方式。

— Reply to this email directly, view it on GitHub https://github.com/ireader/media-server/issues/204#issuecomment-1084058858, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF3RPRMN4LLXZLDDE63WFL3VCUSCHANCNFSM5QB6VYWA . You are receiving this because you authored the thread.Message ID: @.***>

alexliyu7352 commented 2 years ago

只有之前出问题版本的core文件,但是貌似我重新编译后, 因为代码已经修改了. gdb也没办法读取具体的对应堆栈信息了.

现在怎么办?我只能恢复代码然后在部署在生产服务器上?

Chen @.***> 于2022年3月21日周一 15:28写道:

生成coredump文件了吗?

— Reply to this email directly, view it on GitHub https://github.com/ireader/media-server/issues/204#issuecomment-1073552156, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF3RPRIMDNXRC5GQYFYCAM3VBAQLVANCNFSM5QB6VYWA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>