yading@11: /* yading@11: * RTP packetization for MPEG video yading@11: * Copyright (c) 2002 Fabrice Bellard yading@11: * Copyright (c) 2007 Luca Abeni yading@11: * yading@11: * This file is part of FFmpeg. yading@11: * yading@11: * FFmpeg is free software; you can redistribute it and/or yading@11: * modify it under the terms of the GNU Lesser General Public yading@11: * License as published by the Free Software Foundation; either yading@11: * version 2.1 of the License, or (at your option) any later version. yading@11: * yading@11: * FFmpeg is distributed in the hope that it will be useful, yading@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@11: * Lesser General Public License for more details. yading@11: * yading@11: * You should have received a copy of the GNU Lesser General Public yading@11: * License along with FFmpeg; if not, write to the Free Software yading@11: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@11: */ yading@11: yading@11: #include "libavcodec/internal.h" yading@11: #include "avformat.h" yading@11: #include "rtpenc.h" yading@11: yading@11: /* NOTE: a single frame must be passed with sequence header if yading@11: needed. XXX: use slices. */ yading@11: void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size) yading@11: { yading@11: RTPMuxContext *s = s1->priv_data; yading@11: int len, h, max_packet_size; yading@11: uint8_t *q; yading@11: const uint8_t *end = buf1 + size; yading@11: int begin_of_slice, end_of_slice, frame_type, temporal_reference; yading@11: yading@11: max_packet_size = s->max_payload_size; yading@11: begin_of_slice = 1; yading@11: end_of_slice = 0; yading@11: frame_type = 0; yading@11: temporal_reference = 0; yading@11: yading@11: while (size > 0) { yading@11: int begin_of_sequence; yading@11: yading@11: begin_of_sequence = 0; yading@11: len = max_packet_size - 4; yading@11: yading@11: if (len >= size) { yading@11: len = size; yading@11: end_of_slice = 1; yading@11: } else { yading@11: const uint8_t *r, *r1; yading@11: int start_code; yading@11: yading@11: r1 = buf1; yading@11: while (1) { yading@11: start_code = -1; yading@11: r = avpriv_find_start_code(r1, end, &start_code); yading@11: if((start_code & 0xFFFFFF00) == 0x100) { yading@11: /* New start code found */ yading@11: if (start_code == 0x100) { yading@11: frame_type = (r[1] & 0x38) >> 3; yading@11: temporal_reference = (int)r[0] << 2 | r[1] >> 6; yading@11: } yading@11: if (start_code == 0x1B8) { yading@11: begin_of_sequence = 1; yading@11: } yading@11: yading@11: if (r - buf1 - 4 <= len) { yading@11: /* The current slice fits in the packet */ yading@11: if (begin_of_slice == 0) { yading@11: /* no slice at the beginning of the packet... */ yading@11: end_of_slice = 1; yading@11: len = r - buf1 - 4; yading@11: break; yading@11: } yading@11: r1 = r; yading@11: } else { yading@11: if ((r1 - buf1 > 4) && (r - r1 < max_packet_size)) { yading@11: len = r1 - buf1 - 4; yading@11: end_of_slice = 1; yading@11: } yading@11: break; yading@11: } yading@11: } else { yading@11: break; yading@11: } yading@11: } yading@11: } yading@11: yading@11: h = 0; yading@11: h |= temporal_reference << 16; yading@11: h |= begin_of_sequence << 13; yading@11: h |= begin_of_slice << 12; yading@11: h |= end_of_slice << 11; yading@11: h |= frame_type << 8; yading@11: yading@11: q = s->buf; yading@11: *q++ = h >> 24; yading@11: *q++ = h >> 16; yading@11: *q++ = h >> 8; yading@11: *q++ = h; yading@11: yading@11: memcpy(q, buf1, len); yading@11: q += len; yading@11: yading@11: /* 90kHz time stamp */ yading@11: s->timestamp = s->cur_timestamp; yading@11: ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size)); yading@11: yading@11: buf1 += len; yading@11: size -= len; yading@11: begin_of_slice = end_of_slice; yading@11: end_of_slice = 0; yading@11: } yading@11: }