[FFmpeg-devel] [PATCH 2/3] rtpdec_jpeg: use framesize from SDP if present

Andrey Utkin andrey.utkin at corp.bluecherry.net
Tue Dec 8 13:10:32 CET 2015


This enables us to process pics larger than 2040 pixels in dimensions,
overcoming the limitation of RFC 2435.

Signed-off-by: Andrey Utkin <andrey.utkin at corp.bluecherry.net>
---
 libavformat/rtpdec_jpeg.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c
index 6bf88f8..0a83468 100644
--- a/libavformat/rtpdec_jpeg.c
+++ b/libavformat/rtpdec_jpeg.c
@@ -24,9 +24,11 @@
 #include "rtpdec.h"
 #include "rtpdec_formats.h"
 #include "libavutil/intreadwrite.h"
+#include "libavutil/avstring.h"
 #include "libavcodec/jpegtables.h"
 #include "libavcodec/mjpeg.h"
 #include "libavcodec/bytestream.h"
+#include "libavformat/rtpdec_formats.h"
 
 /**
  * RTP/JPEG specific private data.
@@ -35,6 +37,14 @@ struct PayloadContext {
     AVIOContext *frame;         ///< current frame buffer
     uint32_t    timestamp;      ///< current frame timestamp
     int         hdr_size;       ///< size of the current frame header
+    /**
+     * Flag, shows whether we got framesize explicitly from SDP.
+     * If set, override dimensions from RTP header.
+     * Workaround for dimensions larger than 2040 (limitation of RFC 2435).
+     */
+    int         sdp_framesize_set;
+    int         sdp_width;
+    int         sdp_height;
     uint8_t     qtables[128][128];
     uint8_t     qtables_len[128];
 };
@@ -215,7 +225,8 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg,
                              const uint8_t *buf, int len, uint16_t seq,
                              int flags)
 {
-    uint8_t type, q, width, height;
+    uint8_t type, q;
+    uint32_t width, height;
     const uint8_t *qtables = NULL;
     uint16_t qtable_len;
     uint32_t off;
@@ -230,8 +241,13 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg,
     off    = AV_RB24(buf + 1);  /* fragment byte offset */
     type   = AV_RB8(buf + 4);   /* id of jpeg decoder params */
     q      = AV_RB8(buf + 5);   /* quantization factor (or table id) */
-    width  = AV_RB8(buf + 6);   /* frame width in 8 pixel blocks */
-    height = AV_RB8(buf + 7);   /* frame height in 8 pixel blocks */
+    if (jpeg->sdp_framesize_set) {
+        width  = FF_CEIL_RSHIFT(jpeg->sdp_width, 3);
+        height = FF_CEIL_RSHIFT(jpeg->sdp_height, 3);
+    } else {
+        width  = AV_RB8(buf + 6);   /* frame width in 8 pixel blocks */
+        height = AV_RB8(buf + 7);   /* frame height in 8 pixel blocks */
+    }
     buf += 8;
     len -= 8;
 
@@ -384,11 +400,35 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg,
     return AVERROR(EAGAIN);
 }
 
+static int parse_jpeg_sdp_line(AVFormatContext *s, int st_index,
+                               PayloadContext *jpeg_data, const char *line)
+{
+    AVStream *stream;
+    const char *p = line;
+
+    if (st_index < 0)
+        return 0;
+
+    stream = s->streams[st_index];
+
+    if (av_strstart(p, "framesize:", &p)) {
+        ff_h264_parse_framesize(stream->codec, p);
+        av_log(s, AV_LOG_DEBUG, "Got framesize %ux%u from SDP, this will override values from RTP header\n",
+                stream->codec->width, stream->codec->height);
+        jpeg_data->sdp_framesize_set = 1;
+        jpeg_data->sdp_width  = stream->codec->width;
+        jpeg_data->sdp_height = stream->codec->height;
+    }
+
+    return 0;
+}
+
 RTPDynamicProtocolHandler ff_jpeg_dynamic_handler = {
     .enc_name          = "JPEG",
     .codec_type        = AVMEDIA_TYPE_VIDEO,
     .codec_id          = AV_CODEC_ID_MJPEG,
     .priv_data_size    = sizeof(PayloadContext),
+    .parse_sdp_a_line  = parse_jpeg_sdp_line,
     .close             = jpeg_close_context,
     .parse_packet      = jpeg_parse_packet,
     .static_payload_id = 26,
-- 
2.6.3



More information about the ffmpeg-devel mailing list