00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "avformat.h"
00029 #include "avc.h"
00030 #include "rtpenc.h"
00031
00032 static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
00033 {
00034 int res = 0;
00035
00036 if (end - start < nal_length_size)
00037 return NULL;
00038 while (nal_length_size--)
00039 res = (res << 8) | *start++;
00040
00041 if (start + res > end || res < 0 || start + res < start)
00042 return NULL;
00043
00044 return start + res;
00045 }
00046
00047 static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last)
00048 {
00049 RTPMuxContext *s = s1->priv_data;
00050
00051 av_log(s1, AV_LOG_DEBUG, "Sending NAL %x of len %d M=%d\n", buf[0] & 0x1F, size, last);
00052 if (size <= s->max_payload_size) {
00053 ff_rtp_send_data(s1, buf, size, last);
00054 } else {
00055 uint8_t type = buf[0] & 0x1F;
00056 uint8_t nri = buf[0] & 0x60;
00057
00058 av_log(s1, AV_LOG_DEBUG, "NAL size %d > %d\n", size, s->max_payload_size);
00059 s->buf[0] = 28;
00060 s->buf[0] |= nri;
00061 s->buf[1] = type;
00062 s->buf[1] |= 1 << 7;
00063 buf += 1;
00064 size -= 1;
00065 while (size + 2 > s->max_payload_size) {
00066 memcpy(&s->buf[2], buf, s->max_payload_size - 2);
00067 ff_rtp_send_data(s1, s->buf, s->max_payload_size, 0);
00068 buf += s->max_payload_size - 2;
00069 size -= s->max_payload_size - 2;
00070 s->buf[1] &= ~(1 << 7);
00071 }
00072 s->buf[1] |= 1 << 6;
00073 memcpy(&s->buf[2], buf, size);
00074 ff_rtp_send_data(s1, s->buf, size + 2, last);
00075 }
00076 }
00077
00078 void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size)
00079 {
00080 const uint8_t *r, *end = buf1 + size;
00081 RTPMuxContext *s = s1->priv_data;
00082
00083 s->timestamp = s->cur_timestamp;
00084 if (s->nal_length_size)
00085 r = avc_mp4_find_startcode(buf1, end, s->nal_length_size) ? buf1 : end;
00086 else
00087 r = ff_avc_find_startcode(buf1, end);
00088 while (r < end) {
00089 const uint8_t *r1;
00090
00091 if (s->nal_length_size) {
00092 r1 = avc_mp4_find_startcode(r, end, s->nal_length_size);
00093 if (!r1)
00094 r1 = end;
00095 r += s->nal_length_size;
00096 } else {
00097 while (!*(r++));
00098 r1 = ff_avc_find_startcode(r, end);
00099 }
00100 nal_send(s1, r, r1 - r, r1 == end);
00101 r = r1;
00102 }
00103 }