diff options
Diffstat (limited to 'libavformat/rtpenc_hevc.c')
-rw-r--r-- | libavformat/rtpenc_hevc.c | 170 |
1 files changed, 0 insertions, 170 deletions
diff --git a/libavformat/rtpenc_hevc.c b/libavformat/rtpenc_hevc.c deleted file mode 100644 index 1dd3dbf6d1..0000000000 --- a/libavformat/rtpenc_hevc.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * RTP packetizer for HEVC/H.265 payload format (draft version 6) - * Copyright (c) 2014 Thomas Volkert <thomas@homer-conferencing.com> - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" - -#include "avc.h" -#include "avformat.h" -#include "rtpenc.h" - -#define RTP_HEVC_HEADERS_SIZE 3 - -static void flush_buffered(AVFormatContext *s1, int last) -{ - RTPMuxContext *s = s1->priv_data; - if (s->buf_ptr != s->buf) { - // If only sending one single NAL unit, skip the aggregation framing - if (s->buffered_nals == 1) - ff_rtp_send_data(s1, s->buf + 4, s->buf_ptr - s->buf - 4, last); - else - ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, last); - } - s->buf_ptr = s->buf; - s->buffered_nals = 0; -} - -static void nal_send(AVFormatContext *ctx, const uint8_t *buf, int len, int last_packet_of_frame) -{ - RTPMuxContext *rtp_ctx = ctx->priv_data; - int rtp_payload_size = rtp_ctx->max_payload_size - RTP_HEVC_HEADERS_SIZE; - int nal_type = (buf[0] >> 1) & 0x3F; - - /* send it as one single NAL unit? */ - if (len <= rtp_ctx->max_payload_size) { - int buffered_size = rtp_ctx->buf_ptr - rtp_ctx->buf; - /* Flush buffered NAL units if the current unit doesn't fit */ - if (buffered_size + 2 + len > rtp_ctx->max_payload_size) { - flush_buffered(ctx, 0); - buffered_size = 0; - } - /* If the NAL unit fits including the framing, write the unit - * to the buffer as an aggregate packet, otherwise flush and - * send as single NAL. */ - if (buffered_size + 4 + len <= rtp_ctx->max_payload_size) { - if (buffered_size == 0) { - *rtp_ctx->buf_ptr++ = 48 << 1; - *rtp_ctx->buf_ptr++ = 1; - } - AV_WB16(rtp_ctx->buf_ptr, len); - rtp_ctx->buf_ptr += 2; - memcpy(rtp_ctx->buf_ptr, buf, len); - rtp_ctx->buf_ptr += len; - rtp_ctx->buffered_nals++; - } else { - flush_buffered(ctx, 0); - ff_rtp_send_data(ctx, buf, len, last_packet_of_frame); - } - } else { - flush_buffered(ctx, 0); - /* - create the HEVC payload header and transmit the buffer as fragmentation units (FU) - - 0 1 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |F| Type | LayerId | TID | - +-------------+-----------------+ - - F = 0 - Type = 49 (fragmentation unit (FU)) - LayerId = 0 - TID = 1 - */ - rtp_ctx->buf[0] = 49 << 1; - rtp_ctx->buf[1] = 1; - - /* - create the FU header - - 0 1 2 3 4 5 6 7 - +-+-+-+-+-+-+-+-+ - |S|E| FuType | - +---------------+ - - S = variable - E = variable - FuType = NAL unit type - */ - rtp_ctx->buf[2] = nal_type; - /* set the S bit: mark as start fragment */ - rtp_ctx->buf[2] |= 1 << 7; - - /* pass the original NAL header */ - buf += 2; - len -= 2; - - while (len > rtp_payload_size) { - /* complete and send current RTP packet */ - memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, rtp_payload_size); - ff_rtp_send_data(ctx, rtp_ctx->buf, rtp_ctx->max_payload_size, 0); - - buf += rtp_payload_size; - len -= rtp_payload_size; - - /* reset the S bit */ - rtp_ctx->buf[2] &= ~(1 << 7); - } - - /* set the E bit: mark as last fragment */ - rtp_ctx->buf[2] |= 1 << 6; - - /* complete and send last RTP packet */ - memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, len); - ff_rtp_send_data(ctx, rtp_ctx->buf, len + 2, last_packet_of_frame); - } -} - -void ff_rtp_send_hevc(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size) -{ - const uint8_t *next_NAL_unit; - const uint8_t *buf_ptr, *buf_end = frame_buf + frame_size; - RTPMuxContext *rtp_ctx = ctx->priv_data; - - /* use the default 90 KHz time stamp */ - rtp_ctx->timestamp = rtp_ctx->cur_timestamp; - rtp_ctx->buf_ptr = rtp_ctx->buf; - - if (rtp_ctx->nal_length_size) - buf_ptr = ff_avc_mp4_find_startcode(frame_buf, buf_end, rtp_ctx->nal_length_size) ? frame_buf : buf_end; - else - buf_ptr = ff_avc_find_startcode(frame_buf, buf_end); - - /* find all NAL units and send them as separate packets */ - while (buf_ptr < buf_end) { - if (rtp_ctx->nal_length_size) { - next_NAL_unit = ff_avc_mp4_find_startcode(buf_ptr, buf_end, rtp_ctx->nal_length_size); - if (!next_NAL_unit) - next_NAL_unit = buf_end; - - buf_ptr += rtp_ctx->nal_length_size; - } else { - while (!*(buf_ptr++)) - ; - next_NAL_unit = ff_avc_find_startcode(buf_ptr, buf_end); - } - /* send the next NAL unit */ - nal_send(ctx, buf_ptr, next_NAL_unit - buf_ptr, next_NAL_unit == buf_end); - - /* jump to the next NAL unit */ - buf_ptr = next_NAL_unit; - } - flush_buffered(ctx, 1); -} |