diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index e0b2ee4a99..cb2086910e 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -2970,7 +2970,6 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) } if (rt->flv_header_bytes < RTMP_HEADER) { - int set_data_frame = 0; const uint8_t *header = rt->flv_header; int channel = RTMP_AUDIO_CHANNEL; @@ -2991,32 +2990,8 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) if (pkttype == RTMP_PT_VIDEO) channel = RTMP_VIDEO_CHANNEL; - if (pkttype == RTMP_PT_NOTIFY) { - // For onMetaData and |RtmpSampleAccess packets, we want - // @setDataFrame prepended to the packet before it gets sent. - // However, definitely not *all* RTMP_PT_NOTIFY packets (e.g., - // onTextData and onCuePoint). - uint8_t commandbuffer[64]; - int stringlen = 0, commandsize = size - rt->flv_header_bytes; - GetByteContext gbc; - - // buf_temp at this point should be pointing to the RTMP command - bytestream2_init(&gbc, buf_temp, commandsize); - if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer), - &stringlen)) - return AVERROR_INVALIDDATA; - - if (!strcmp(commandbuffer, "onMetaData") || - !strcmp(commandbuffer, "|RtmpSampleAccess")) { - set_data_frame = 1; - } - } - if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) || pkttype == RTMP_PT_NOTIFY) { - // add 12 bytes header if passing @setDataFrame - if (set_data_frame) - pktsize += 16; if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1], &rt->nb_prev_pkt[1], channel)) < 0) @@ -3034,10 +3009,6 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) rt->out_pkt.extra = rt->stream_id; rt->flv_data = rt->out_pkt.data; - - if (set_data_frame) { - ff_amf_write_string(&rt->flv_data, "@setDataFrame"); - } } copy = FFMIN(rt->flv_size - rt->flv_off, size_temp); @@ -3048,6 +3019,33 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) if (rt->flv_off == rt->flv_size) { rt->skip_bytes = 4; + if (rt->out_pkt.type == RTMP_PT_NOTIFY) { + // For onMetaData and |RtmpSampleAccess packets, we want + // @setDataFrame prepended to the packet before it gets sent. + // However, not all RTMP_PT_NOTIFY packets (e.g., onTextData + // and onCuePoint). + uint8_t commandbuffer[64]; + int stringlen = 0; + GetByteContext gbc; + + bytestream2_init(&gbc, rt->flv_data, rt->flv_size); + if (!ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer), + &stringlen)) { + if (!strcmp(commandbuffer, "onMetaData") || + !strcmp(commandbuffer, "|RtmpSampleAccess")) { + uint8_t *ptr; + if ((ret = av_reallocp(&rt->out_pkt.data, rt->out_pkt.size + 16)) < 0) { + rt->flv_size = rt->flv_off = rt->flv_header_bytes = 0; + return ret; + } + memmove(rt->out_pkt.data + 16, rt->out_pkt.data, rt->out_pkt.size); + rt->out_pkt.size += 16; + ptr = rt->out_pkt.data; + ff_amf_write_string(&ptr, "@setDataFrame"); + } + } + } + if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0) return ret; rt->flv_size = 0;