diff --git a/libavformat/Makefile b/libavformat/Makefile index 794d2126e2..8accc8a220 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -119,7 +119,7 @@ OBJS-$(CONFIG_RM_DEMUXER) += rmdec.o OBJS-$(CONFIG_RM_MUXER) += rmenc.o OBJS-$(CONFIG_ROQ_DEMUXER) += idroq.o OBJS-$(CONFIG_ROQ_MUXER) += raw.o -OBJS-$(CONFIG_RTP_MUXER) += rtp.o rtp_h264.o +OBJS-$(CONFIG_RTP_MUXER) += rtp.o rtp_h264.o rtp_mpv.o OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o diff --git a/libavformat/rtp.c b/libavformat/rtp.c index e42cfb16d4..f45ad3752e 100644 --- a/libavformat/rtp.c +++ b/libavformat/rtp.c @@ -27,6 +27,7 @@ #include "rtp_internal.h" #include "rtp_h264.h" +#include "rtp_mpv.h" //#define DEBUG @@ -788,7 +789,7 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time) /* send an rtp packet. sequence number is incremented, but the caller must update the timestamp itself */ -static void rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m) +void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m) { RTPDemuxContext *s = s1->priv_data; @@ -836,7 +837,7 @@ static void rtp_send_samples(AVFormatContext *s1, n = (s->buf_ptr - s->buf); /* if buffer full, then send it */ if (n >= max_packet_size) { - rtp_send_data(s1, s->buf, n, 0); + ff_rtp_send_data(s1, s->buf, n, 0); s->buf_ptr = s->buf; /* update timestamp */ s->timestamp += n / sample_size; @@ -859,7 +860,7 @@ static void rtp_send_mpegaudio(AVFormatContext *s1, len = (s->buf_ptr - s->buf); if ((len + size) > max_packet_size) { if (len > 4) { - rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0); + ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0); s->buf_ptr = s->buf + 4; /* 90 KHz time stamp */ s->timestamp = s->base_timestamp + @@ -881,7 +882,7 @@ static void rtp_send_mpegaudio(AVFormatContext *s1, s->buf[2] = count >> 8; s->buf[3] = count; memcpy(s->buf + 4, buf1, len); - rtp_send_data(s1, s->buf, len + 4, 0); + ff_rtp_send_data(s1, s->buf, len + 4, 0); size -= len; buf1 += len; count += len; @@ -900,55 +901,6 @@ static void rtp_send_mpegaudio(AVFormatContext *s1, s->cur_timestamp += st->codec->frame_size; } -/* NOTE: a single frame must be passed with sequence header if - needed. XXX: use slices. */ -static void rtp_send_mpegvideo(AVFormatContext *s1, - const uint8_t *buf1, int size) -{ - RTPDemuxContext *s = s1->priv_data; - AVStream *st = s1->streams[0]; - int len, h, max_packet_size; - uint8_t *q; - - max_packet_size = s->max_payload_size; - - while (size > 0) { - /* XXX: more correct headers */ - h = 0; - if (st->codec->sub_id == 2) - h |= 1 << 26; /* mpeg 2 indicator */ - q = s->buf; - *q++ = h >> 24; - *q++ = h >> 16; - *q++ = h >> 8; - *q++ = h; - - if (st->codec->sub_id == 2) { - h = 0; - *q++ = h >> 24; - *q++ = h >> 16; - *q++ = h >> 8; - *q++ = h; - } - - len = max_packet_size - (q - s->buf); - if (len > size) - len = size; - - memcpy(q, buf1, len); - q += len; - - /* 90 KHz time stamp */ - s->timestamp = s->base_timestamp + - av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps - rtp_send_data(s1, s->buf, q - s->buf, (len == size)); - - buf1 += len; - size -= len; - } - s->cur_timestamp++; -} - static void rtp_send_raw(AVFormatContext *s1, const uint8_t *buf1, int size) { @@ -966,7 +918,7 @@ static void rtp_send_raw(AVFormatContext *s1, /* 90 KHz time stamp */ s->timestamp = s->base_timestamp + av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps - rtp_send_data(s1, buf1, len, (len == size)); + ff_rtp_send_data(s1, buf1, len, (len == size)); buf1 += len; size -= len; @@ -992,7 +944,7 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1, out_len = s->buf_ptr - s->buf; if (out_len >= s->max_payload_size) { - rtp_send_data(s1, s->buf, out_len, 0); + ff_rtp_send_data(s1, s->buf, out_len, 0); s->buf_ptr = s->buf; } } @@ -1042,7 +994,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) rtp_send_mpegaudio(s1, buf1, size); break; case CODEC_ID_MPEG1VIDEO: - rtp_send_mpegvideo(s1, buf1, size); + ff_rtp_send_mpegvideo(s1, buf1, size); break; case CODEC_ID_MPEG2TS: rtp_send_mpegts_raw(s1, buf1, size); diff --git a/libavformat/rtp_internal.h b/libavformat/rtp_internal.h index 882098faba..b03f74e861 100644 --- a/libavformat/rtp_internal.h +++ b/libavformat/rtp_internal.h @@ -110,5 +110,7 @@ struct RTPDemuxContext { extern RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler; int rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size); ///< from rtsp.c, but used by rtp dynamic protocol handlers. + +void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m); #endif /* RTP_INTERNAL_H */ diff --git a/libavformat/rtp_mpv.c b/libavformat/rtp_mpv.c new file mode 100644 index 0000000000..0db6663cbd --- /dev/null +++ b/libavformat/rtp_mpv.c @@ -0,0 +1,72 @@ +/* + * RTP packetization for MPEG video + * Copyright (c) 2002 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avformat.h" +#include "rtp_internal.h" + +/* NOTE: a single frame must be passed with sequence header if + needed. XXX: use slices. */ +void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size) +{ + RTPDemuxContext *s = s1->priv_data; + AVStream *st = s1->streams[0]; + int len, h, max_packet_size; + uint8_t *q; + + max_packet_size = s->max_payload_size; + + while (size > 0) { + /* XXX: more correct headers */ + h = 0; + if (st->codec->sub_id == 2) + h |= 1 << 26; /* mpeg 2 indicator */ + q = s->buf; + *q++ = h >> 24; + *q++ = h >> 16; + *q++ = h >> 8; + *q++ = h; + + if (st->codec->sub_id == 2) { + h = 0; + *q++ = h >> 24; + *q++ = h >> 16; + *q++ = h >> 8; + *q++ = h; + } + + len = max_packet_size - (q - s->buf); + if (len > size) + len = size; + + memcpy(q, buf1, len); + q += len; + + /* 90 KHz time stamp */ + s->timestamp = s->base_timestamp + + av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps + ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size)); + + buf1 += len; + size -= len; + } + s->cur_timestamp++; +} + + diff --git a/libavformat/rtp_mpv.h b/libavformat/rtp_mpv.h new file mode 100644 index 0000000000..fb09a25011 --- /dev/null +++ b/libavformat/rtp_mpv.h @@ -0,0 +1,26 @@ +/* + * RTP definitions + * Copyright (c) 2002 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef RTP_MPV_H +#define RTP_MPV_H + +void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size); + +#endif /* RTP_MPV_H */