首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在FFmpeg的libavformat中修改RTMP

在FFmpeg的libavformat中修改RTMP
EN

Stack Overflow用户
提问于 2017-07-05 18:45:51
回答 1查看 673关注 0票数 0

我需要将Stream Dry消息发送到我的应用程序流式传输到的RTMP服务器。我创建了一个在avformat.h .h上声明并在rtmpproto.c上定义的新函数,它包含以下内容:

代码语言:javascript
复制
int av_send_rtmp_streamdry(struct URLContext *s) {
RTMPContext *rt = s->priv_data;
PutByteContext pbc;
RTMPPacket spkt = { 0 };
int ret;
uint8_t *p;

av_log(s, AV_LOG_INFO, "%p", rt);

// Create StreamDry packet
// The packet type is the same as the PING response type. From RTMP spec,
// packet type 4 belongs to User Control Messages.
// The packet size is Event Type (16 bits / 2 bytes) + Stream ID (4 bytes)
if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
                                 RTMP_PT_PING, 0, 6)) < 0) {
    av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
    return ret;
}
p = spkt.data;
bytestream2_init_writer(&pbc, spkt.data, spkt.size);
bytestream2_put_be16(&pbc, 2);          // 2 -> Stream Dry
bytestream2_put_be32(&pbc, rt->stream_id);
spkt.size = p - spkt.data;
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
                           &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);

if(ret != 0){
    av_log(NULL, AV_LOG_ERROR, "Stream Dry packet could not be sent");
    return ret;
}

ff_rtmp_packet_destroy(&spkt);

return 0;}

我通过static_cast<URLContext*>(ofmt_ctx->pb->opaque)获取URLContext,其中ofmt是我的AVFormatContext。我直接从我的程序中调用这个方法,但问题是s->priv_data内容几乎不是一个有效的指针。

我如何实现这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-06 00:41:30

最后,我可以实现该函数。问题是试图从AVFormatContext获取RTMPContext时的强制转换问题。

AVFormatContext字段'pb‘包含AVIOContext*。

AVIOContext字段'opaque‘包含一个空*,但在我的例子中(我不知道它是否总是这样)是一个AVIOInternal*。AVIOInternal包含我需要的URLContext*,但是因为它是在'aviobuf.c‘文件中定义的,所以我无法访问它,但它只包含一个字段。因此,解决方案是绕过AVIOInternal结构,将“opaque”字段从AVIOContext转换为URLContext**。所以下面的代码就是解决方案:

代码语言:javascript
复制
AVIOContext *io = output->pb;
URLContext *url = *((URLContext**)(io->opaque));
RTMPContext *rt =(RTMPContext*)(url->priv_data);

编辑:这是完整的工作代码。

代码语言:javascript
复制
int av_send_rtmp_streamdry(AVFormatContext *output) {
    AVIOContext *io = output->pb;
    URLContext *url = *((URLContext**)(io->opaque));
    RTMPContext *rt =(RTMPContext*)(url->priv_data);
    PutByteContext pbc;
    RTMPPacket spkt = { 0 };
    int ret;
    uint8_t *p;

    // Create StreamDry packet
    // The packet type is the same as the PING response type. From RTMP spec,
    // packet type 4 belongs to User Control Messages.
    // The packet size is Event Type (16 bits / 2 bytes) + Stream ID (4 bytes)
    if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
                                     RTMP_PT_PING, 0, 6)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Unable to create response packet\n");
        return ret;
    }
    bytestream2_init_writer(&pbc, spkt.data, spkt.size);
    bytestream2_put_be16(&pbc, 2);          // 2 -> Stream Dry
    bytestream2_put_be32(&pbc, rt->stream_id);
    ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
    ff_rtmp_packet_destroy(&spkt);

    if(ret < 0){
        av_log(NULL, AV_LOG_ERROR, "Stream Dry packet could not be sent");
        return ret;
    }

    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44924071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档