Libav
|
00001 /* 00002 * RTP packetization for MPEG video 00003 * Copyright (c) 2002 Fabrice Bellard 00004 * Copyright (c) 2007 Luca Abeni 00005 * 00006 * This file is part of FFmpeg. 00007 * 00008 * FFmpeg is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * FFmpeg is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with FFmpeg; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #include "libavcodec/mpegvideo.h" 00024 #include "avformat.h" 00025 #include "rtpenc.h" 00026 00027 /* NOTE: a single frame must be passed with sequence header if 00028 needed. XXX: use slices. */ 00029 void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size) 00030 { 00031 RTPMuxContext *s = s1->priv_data; 00032 int len, h, max_packet_size; 00033 uint8_t *q; 00034 const uint8_t *end = buf1 + size; 00035 int begin_of_slice, end_of_slice, frame_type, temporal_reference; 00036 00037 max_packet_size = s->max_payload_size; 00038 begin_of_slice = 1; 00039 end_of_slice = 0; 00040 frame_type = 0; 00041 temporal_reference = 0; 00042 00043 while (size > 0) { 00044 int begin_of_sequence; 00045 00046 begin_of_sequence = 0; 00047 len = max_packet_size - 4; 00048 00049 if (len >= size) { 00050 len = size; 00051 end_of_slice = 1; 00052 } else { 00053 const uint8_t *r, *r1; 00054 int start_code; 00055 00056 r1 = buf1; 00057 while (1) { 00058 start_code = -1; 00059 r = ff_find_start_code(r1, end, &start_code); 00060 if((start_code & 0xFFFFFF00) == 0x100) { 00061 /* New start code found */ 00062 if (start_code == 0x100) { 00063 frame_type = (r[1] & 0x38) >> 3; 00064 temporal_reference = (int)r[0] << 2 | r[1] >> 6; 00065 } 00066 if (start_code == 0x1B8) { 00067 begin_of_sequence = 1; 00068 } 00069 00070 if (r - buf1 - 4 <= len) { 00071 /* The current slice fits in the packet */ 00072 if (begin_of_slice == 0) { 00073 /* no slice at the beginning of the packet... */ 00074 end_of_slice = 1; 00075 len = r - buf1 - 4; 00076 break; 00077 } 00078 r1 = r; 00079 } else { 00080 if ((r1 - buf1 > 4) && (r - r1 < max_packet_size)) { 00081 len = r1 - buf1 - 4; 00082 end_of_slice = 1; 00083 } 00084 break; 00085 } 00086 } else { 00087 break; 00088 } 00089 } 00090 } 00091 00092 h = 0; 00093 h |= temporal_reference << 16; 00094 h |= begin_of_sequence << 13; 00095 h |= begin_of_slice << 12; 00096 h |= end_of_slice << 11; 00097 h |= frame_type << 8; 00098 00099 q = s->buf; 00100 *q++ = h >> 24; 00101 *q++ = h >> 16; 00102 *q++ = h >> 8; 00103 *q++ = h; 00104 00105 memcpy(q, buf1, len); 00106 q += len; 00107 00108 /* 90kHz time stamp */ 00109 s->timestamp = s->cur_timestamp; 00110 ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size)); 00111 00112 buf1 += len; 00113 size -= len; 00114 begin_of_slice = end_of_slice; 00115 end_of_slice = 0; 00116 } 00117 } 00118 00119