diff options
author | Michael Niedermayer | 2012-09-24 13:53:32 +0200 |
---|---|---|
committer | Michael Niedermayer | 2012-09-24 13:54:24 +0200 |
commit | ff584803b7ea31febb3f57124a3702d13c27e24c (patch) | |
tree | b8f22d7053d443db3929d5fe210a2c1a18eca3c8 | |
parent | 874b9dcc4be78847e488df33aad51752a8bebc2e (diff) | |
parent | cee1950bbb44acd215efd2101fb52d9605701969 (diff) |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
rtp: Packetization of JPEG (RFC 2435)
smoothstreamingenc: Copy the SAR on the AVStreams as well
Conflicts:
Changelog
libavformat/rtpenc.c
libavformat/version.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/rtpenc.c | 4 | ||||
-rw-r--r-- | libavformat/rtpenc.h | 1 | ||||
-rw-r--r-- | libavformat/rtpenc_jpeg.c | 138 | ||||
-rw-r--r-- | libavformat/sdp.c | 5 | ||||
-rw-r--r-- | libavformat/smoothstreamingenc.c | 1 | ||||
-rw-r--r-- | libavformat/version.h | 2 |
8 files changed, 152 insertions, 1 deletions
@@ -64,6 +64,7 @@ version next: - F4V muxer - sendcmd and asendcmd filters - WebVTT demuxer and decoder (simple tags supported) +- RTP packetization of JPEG version 0.11: diff --git a/libavformat/Makefile b/libavformat/Makefile index 632721f4bb..01d750d4d3 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -277,6 +277,7 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ rtpenc_amr.o \ rtpenc_h263.o \ rtpenc_h263_rfc2190.o \ + rtpenc_jpeg.o \ rtpenc_mpv.o \ rtpenc.o \ rtpenc_h264.o \ diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 3a3e3d8ee2..653eded94c 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -76,6 +76,7 @@ static int is_supported(enum AVCodecID id) case AV_CODEC_ID_ADPCM_G726: case AV_CODEC_ID_ILBC: case AV_CODEC_ID_SPEEX: + case AV_CODEC_ID_MJPEG: return 1; default: return 0; @@ -525,6 +526,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) case AV_CODEC_ID_ILBC: rtp_send_ilbc(s1, pkt->data, size); break; + case AV_CODEC_ID_MJPEG: + ff_rtp_send_jpeg(s1, pkt->data, size); + break; default: /* better than nothing : send the codec raw data */ rtp_send_raw(s1, pkt->data, size); diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h index 4b3f5dbc6d..bc523b442a 100644 --- a/libavformat/rtpenc.h +++ b/libavformat/rtpenc.h @@ -87,6 +87,7 @@ void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size); void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size); void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size); void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t *buff, int size); +void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buff, int size); const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *av_restrict start, const uint8_t *av_restrict end); diff --git a/libavformat/rtpenc_jpeg.c b/libavformat/rtpenc_jpeg.c new file mode 100644 index 0000000000..b2cfb8d5c0 --- /dev/null +++ b/libavformat/rtpenc_jpeg.c @@ -0,0 +1,138 @@ +/* + * RTP JPEG-compressed video Packetizer, RFC 2435 + * Copyright (c) 2012 Samuel Pitoiset + * + * 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 "libavcodec/bytestream.h" +#include "libavcodec/mjpeg.h" +#include "libavutil/intreadwrite.h" +#include "rtpenc.h" + +void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size) +{ + RTPMuxContext *s = s1->priv_data; + const uint8_t *qtables = NULL; + int nb_qtables = 0; + uint8_t type = 1; /* default pixel format is PIX_FMT_YUVJ420P */ + uint8_t w, h; + uint8_t *p; + int off = 0; /* fragment offset of the current JPEG frame */ + int len; + int i; + + s->buf_ptr = s->buf; + s->timestamp = s->cur_timestamp; + + /* convert video pixel dimensions from pixels to blocks */ + w = s1->streams[0]->codec->width >> 3; + h = s1->streams[0]->codec->height >> 3; + + /* check if pixel format is not the normal 420 case */ + if (s1->streams[0]->codec->pix_fmt == PIX_FMT_YUVJ422P) { + type = 0; + } else if (s1->streams[0]->codec->pix_fmt == PIX_FMT_YUVJ420P) { + type = 1; + } else { + av_log(s1, AV_LOG_ERROR, "Unsupported pixel format\n"); + return; + } + + /* preparse the header for getting some infos */ + for (i = 0; i < size; i++) { + if (buf[i] != 0xff) + continue; + + if (buf[i + 1] == DQT) { + if (buf[i + 4]) + av_log(s1, AV_LOG_WARNING, + "Only 8-bit precision is supported.\n"); + + /* a quantization table is 64 bytes long */ + nb_qtables = AV_RB16(&buf[i + 2]) / 65; + if (i + 4 + nb_qtables * 65 > size) { + av_log(s1, AV_LOG_ERROR, "Too short JPEG header. Aborted!\n"); + return; + } + + qtables = &buf[i + 4]; + } else if (buf[i + 1] == SOF0) { + if (buf[i + 14] != 17 || buf[i + 17] != 17) { + av_log(s1, AV_LOG_ERROR, + "Only 1x1 chroma blocks are supported. Aborted!\n"); + return; + } + } else if (buf[i + 1] == SOS) { + /* SOS is last marker in the header */ + i += AV_RB16(&buf[i + 2]) + 2; + break; + } + } + + /* skip JPEG header */ + buf += i; + size -= i; + + for (i = size - 2; i >= 0; i--) { + if (buf[i] == 0xff && buf[i + 1] == EOI) { + /* Remove the EOI marker */ + size = i; + break; + } + } + + p = s->buf_ptr; + while (size > 0) { + int hdr_size = 8; + + if (off == 0 && nb_qtables) + hdr_size += 4 + 64 * nb_qtables; + + /* payload max in one packet */ + len = FFMIN(size, s->max_payload_size - hdr_size); + + /* set main header */ + bytestream_put_byte(&p, 0); + bytestream_put_be24(&p, off); + bytestream_put_byte(&p, type); + bytestream_put_byte(&p, 255); + bytestream_put_byte(&p, w); + bytestream_put_byte(&p, h); + + if (off == 0 && nb_qtables) { + /* set quantization tables header */ + bytestream_put_byte(&p, 0); + bytestream_put_byte(&p, 0); + bytestream_put_be16(&p, 64 * nb_qtables); + + for (i = 0; i < nb_qtables; i++) + bytestream_put_buffer(&p, &qtables[65 * i + 1], 64); + } + + /* copy payload data */ + memcpy(p, buf, len); + + /* marker bit is last packet in frame */ + ff_rtp_send_data(s1, s->buf, len + hdr_size, size == len); + + buf += len; + size -= len; + off += len; + p = s->buf; + } +} diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 8ff4325817..96b6c44e05 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -547,6 +547,11 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n", payload_type); break; + case AV_CODEC_ID_MJPEG: + if (payload_type >= RTP_PT_PRIVATE) + av_strlcatf(buff, size, "a=rtpmap:%d JPEG/90000\r\n", + payload_type); + break; case AV_CODEC_ID_ADPCM_G722: if (payload_type >= RTP_PT_PRIVATE) av_strlcatf(buff, size, "a=rtpmap:%d G722/%d/%d\r\n", diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index eba6542d9e..2dfc26f8d8 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -239,6 +239,7 @@ static int ism_write_header(AVFormatContext *s) goto fail; } avcodec_copy_context(st->codec, s->streams[i]->codec); + st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, ism_write, ism_seek); if (!ctx->pb) { diff --git a/libavformat/version.h b/libavformat/version.h index fe3e6f8671..55c7638f02 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 28 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ |