1/* 2 * RTP packetization for H.264 (RFC3984) 3 * Copyright (c) 2008 Luca Abeni 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file libavformat/rtpenc_h264.c 24 * @brief H.264 packetization 25 * @author Luca Abeni <lucabe72@email.it> 26 */ 27 28#include "avformat.h" 29#include "avc.h" 30#include "rtpenc.h" 31 32static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last) 33{ 34 RTPMuxContext *s = s1->priv_data; 35 36 av_log(s1, AV_LOG_DEBUG, "Sending NAL %x of len %d M=%d\n", buf[0] & 0x1F, size, last); 37 if (size <= s->max_payload_size) { 38 ff_rtp_send_data(s1, buf, size, last); 39 } else { 40 uint8_t type = buf[0] & 0x1F; 41 uint8_t nri = buf[0] & 0x60; 42 43 av_log(s1, AV_LOG_DEBUG, "NAL size %d > %d\n", size, s->max_payload_size); 44 s->buf[0] = 28; /* FU Indicator; Type = 28 ---> FU-A */ 45 s->buf[0] |= nri; 46 s->buf[1] = type; 47 s->buf[1] |= 1 << 7; 48 buf += 1; 49 size -= 1; 50 while (size + 2 > s->max_payload_size) { 51 memcpy(&s->buf[2], buf, s->max_payload_size - 2); 52 ff_rtp_send_data(s1, s->buf, s->max_payload_size, 0); 53 buf += s->max_payload_size - 2; 54 size -= s->max_payload_size - 2; 55 s->buf[1] &= ~(1 << 7); 56 } 57 s->buf[1] |= 1 << 6; 58 memcpy(&s->buf[2], buf, size); 59 ff_rtp_send_data(s1, s->buf, size + 2, 1); 60 } 61} 62 63void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size) 64{ 65 const uint8_t *r; 66 RTPMuxContext *s = s1->priv_data; 67 68 s->timestamp = s->cur_timestamp; 69 r = ff_avc_find_startcode(buf1, buf1 + size); 70 while (r < buf1 + size) { 71 const uint8_t *r1; 72 73 while(!*(r++)); 74 r1 = ff_avc_find_startcode(r, buf1 + size); 75 nal_send(s1, r, r1 - r, (r1 == buf1 + size)); 76 r = r1; 77 } 78} 79