From 7ef4323405fae8f62732111b747d585ef9c786c7 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 11:03:05 +0300 Subject: rtpdec_jpeg: Write the DHT section properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the size header of the generated DHT section is incorrect, making the mjpeg decoder just skip it. Since the written huffman tables are the default ones, this failure had gone undetected. Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 671763d289..19ecbf47fa 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -76,13 +76,12 @@ static void jpeg_free_context(PayloadContext *jpeg) av_free(jpeg); } -static void jpeg_create_huffman_table(PutBitContext *p, int table_class, - int table_id, const uint8_t *bits_table, - const uint8_t *value_table) +static int jpeg_create_huffman_table(PutBitContext *p, int table_class, + int table_id, const uint8_t *bits_table, + const uint8_t *value_table) { int i, n = 0; - put_bits(p, 8, 0); put_bits(p, 4, table_class); put_bits(p, 4, table_id); @@ -94,12 +93,15 @@ static void jpeg_create_huffman_table(PutBitContext *p, int table_class, for (i = 0; i < n; i++) { put_bits(p, 8, value_table[i]); } + return n + 17; } static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, uint32_t h, const uint8_t *qtable, int nb_qtable) { PutBitContext pbc; + uint8_t *dht_size_ptr; + int dht_size; init_put_bits(&pbc, buf, size); @@ -142,15 +144,20 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, /* DHT */ put_marker(&pbc, DHT); - - jpeg_create_huffman_table(&pbc, 0, 0, avpriv_mjpeg_bits_dc_luminance, - avpriv_mjpeg_val_dc); - jpeg_create_huffman_table(&pbc, 0, 1, avpriv_mjpeg_bits_dc_chrominance, - avpriv_mjpeg_val_dc); - jpeg_create_huffman_table(&pbc, 1, 0, avpriv_mjpeg_bits_ac_luminance, - avpriv_mjpeg_val_ac_luminance); - jpeg_create_huffman_table(&pbc, 1, 1, avpriv_mjpeg_bits_ac_chrominance, - avpriv_mjpeg_val_ac_chrominance); + flush_put_bits(&pbc); + dht_size_ptr = put_bits_ptr(&pbc); + put_bits(&pbc, 16, 0); + + dht_size = 2; + dht_size += jpeg_create_huffman_table(&pbc, 0, 0,avpriv_mjpeg_bits_dc_luminance, + avpriv_mjpeg_val_dc); + dht_size += jpeg_create_huffman_table(&pbc, 0, 1, avpriv_mjpeg_bits_dc_chrominance, + avpriv_mjpeg_val_dc); + dht_size += jpeg_create_huffman_table(&pbc, 1, 0, avpriv_mjpeg_bits_ac_luminance, + avpriv_mjpeg_val_ac_luminance); + dht_size += jpeg_create_huffman_table(&pbc, 1, 1, avpriv_mjpeg_bits_ac_chrominance, + avpriv_mjpeg_val_ac_chrominance); + AV_WB16(dht_size_ptr, dht_size); /* SOF0 */ put_marker(&pbc, SOF0); -- cgit v1.2.3 From 932d8300d38587ebc223e3bacc3c33ed68bf3cf6 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 12:07:56 +0300 Subject: rtpdec_jpeg: Merge two if statements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the code more readable and robust. Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 61 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 31 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 19ecbf47fa..0513b09b3d 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -252,44 +252,43 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, } /* Parse the quantization table header. */ - if (q > 127 && off == 0) { - uint8_t precision; - - if (len < 4) { - av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); - return AVERROR_INVALIDDATA; - } + if (off == 0) { + /* Start of JPEG data packet. */ + uint8_t new_qtables[128]; + uint8_t hdr[1024]; - /* The first byte is reserved for future use. */ - precision = AV_RB8(buf + 1); /* size of coefficients */ - qtable_len = AV_RB16(buf + 2); /* length in bytes */ - buf += 4; - len -= 4; + if (q > 127) { + uint8_t precision; + if (len < 4) { + av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); + return AVERROR_INVALIDDATA; + } - if (precision) - av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n"); + /* The first byte is reserved for future use. */ + precision = AV_RB8(buf + 1); /* size of coefficients */ + qtable_len = AV_RB16(buf + 2); /* length in bytes */ + buf += 4; + len -= 4; - if (q == 255 && qtable_len == 0) { - av_log(ctx, AV_LOG_ERROR, - "Invalid RTP/JPEG packet. Quantization tables not found.\n"); - return AVERROR_INVALIDDATA; - } + if (precision) + av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n"); - if (qtable_len > 0) { - if (len < qtable_len) { - av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); + if (q == 255 && qtable_len == 0) { + av_log(ctx, AV_LOG_ERROR, + "Invalid RTP/JPEG packet. Quantization tables not found.\n"); return AVERROR_INVALIDDATA; } - qtables = buf; - buf += qtable_len; - len -= qtable_len; - } - } - if (off == 0) { - /* Start of JPEG data packet. */ - uint8_t new_qtables[128]; - uint8_t hdr[1024]; + if (qtable_len > 0) { + if (len < qtable_len) { + av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); + return AVERROR_INVALIDDATA; + } + qtables = buf; + buf += qtable_len; + len -= qtable_len; + } + } /* Skip the current frame in case of the end packet * has been lost somewhere. */ -- cgit v1.2.3 From 43957fcc71c08697eea7c684900ac793c87e487c Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 12:32:37 +0300 Subject: rtpdec_jpeg: Simplify writing of the jpeg header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalize writing of any number of qtables. Don't manually write 16 bit values in two separate calls. Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 0513b09b3d..1c75c47137 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -101,7 +101,7 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, { PutBitContext pbc; uint8_t *dht_size_ptr; - int dht_size; + int dht_size, i; init_put_bits(&pbc, buf, size); @@ -125,21 +125,15 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, /* DQT */ put_marker(&pbc, DQT); - if (nb_qtable == 2) { - put_bits(&pbc, 16, 2 + 2 * (1 + 64)); - } else { - put_bits(&pbc, 16, 2 + 1 * (1 + 64)); - } - put_bits(&pbc, 8, 0); + put_bits(&pbc, 16, 2 + nb_qtable * (1 + 64)); - /* Each table is an array of 64 values given in zig-zag - * order, identical to the format used in a JFIF DQT - * marker segment. */ - avpriv_copy_bits(&pbc, qtable, 64 * 8); + for (i = 0; i < nb_qtable; i++) { + put_bits(&pbc, 8, i); - if (nb_qtable == 2) { - put_bits(&pbc, 8, 1); - avpriv_copy_bits(&pbc, qtable + 64, 64 * 8); + /* Each table is an array of 64 values given in zig-zag + * order, identical to the format used in a JFIF DQT + * marker segment. */ + avpriv_copy_bits(&pbc, qtable + 64 * i, 64 * 8); } /* DHT */ @@ -163,10 +157,8 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, put_marker(&pbc, SOF0); put_bits(&pbc, 16, 17); put_bits(&pbc, 8, 8); - put_bits(&pbc, 8, h >> 8); - put_bits(&pbc, 8, h); - put_bits(&pbc, 8, w >> 8); - put_bits(&pbc, 8, w); + put_bits(&pbc, 16, h); + put_bits(&pbc, 16, w); put_bits(&pbc, 8, 3); put_bits(&pbc, 8, 1); put_bits(&pbc, 8, type ? 34 : 33); -- cgit v1.2.3 From 20f325f320c6e18ee88983870d2a1fee94257293 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 12:44:25 +0300 Subject: rtpdec_jpeg: Don't needlessly use a bitstream writer for the header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Everything written with this bitstream writer is 8/16 bit units (except for a pair of 4 bit values), so using a bitstream writer isn't necessary. Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 114 +++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 56 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 1c75c47137..4f52c31b9f 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -23,6 +23,7 @@ #include "rtpdec_formats.h" #include "libavutil/intreadwrite.h" #include "libavcodec/mjpeg.h" +#include "libavcodec/bytestream.h" /** * RTP/JPEG specific private data. @@ -76,71 +77,75 @@ static void jpeg_free_context(PayloadContext *jpeg) av_free(jpeg); } -static int jpeg_create_huffman_table(PutBitContext *p, int table_class, +static int jpeg_create_huffman_table(PutByteContext *p, int table_class, int table_id, const uint8_t *bits_table, const uint8_t *value_table) { int i, n = 0; - put_bits(p, 4, table_class); - put_bits(p, 4, table_id); + bytestream2_put_byte(p, table_class << 4 | table_id); for (i = 1; i <= 16; i++) { n += bits_table[i]; - put_bits(p, 8, bits_table[i]); + bytestream2_put_byte(p, bits_table[i]); } for (i = 0; i < n; i++) { - put_bits(p, 8, value_table[i]); + bytestream2_put_byte(p, value_table[i]); } return n + 17; } +static void jpeg_put_marker(PutByteContext *pbc, int code) +{ + bytestream2_put_byte(pbc, 0xff); + bytestream2_put_byte(pbc, code); +} + static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, uint32_t h, const uint8_t *qtable, int nb_qtable) { - PutBitContext pbc; + PutByteContext pbc; uint8_t *dht_size_ptr; int dht_size, i; - init_put_bits(&pbc, buf, size); + bytestream2_init_writer(&pbc, buf, size); /* Convert from blocks to pixels. */ w <<= 3; h <<= 3; /* SOI */ - put_marker(&pbc, SOI); + jpeg_put_marker(&pbc, SOI); /* JFIF header */ - put_marker(&pbc, APP0); - put_bits(&pbc, 16, 16); - avpriv_put_string(&pbc, "JFIF", 1); - put_bits(&pbc, 16, 0x0201); - put_bits(&pbc, 8, 0); - put_bits(&pbc, 16, 1); - put_bits(&pbc, 16, 1); - put_bits(&pbc, 8, 0); - put_bits(&pbc, 8, 0); + jpeg_put_marker(&pbc, APP0); + bytestream2_put_be16(&pbc, 16); + bytestream2_put_buffer(&pbc, "JFIF", 5); + bytestream2_put_be16(&pbc, 0x0201); + bytestream2_put_byte(&pbc, 0); + bytestream2_put_be16(&pbc, 1); + bytestream2_put_be16(&pbc, 1); + bytestream2_put_byte(&pbc, 0); + bytestream2_put_byte(&pbc, 0); /* DQT */ - put_marker(&pbc, DQT); - put_bits(&pbc, 16, 2 + nb_qtable * (1 + 64)); + jpeg_put_marker(&pbc, DQT); + bytestream2_put_be16(&pbc, 2 + nb_qtable * (1 + 64)); for (i = 0; i < nb_qtable; i++) { - put_bits(&pbc, 8, i); + bytestream2_put_byte(&pbc, i); /* Each table is an array of 64 values given in zig-zag * order, identical to the format used in a JFIF DQT * marker segment. */ - avpriv_copy_bits(&pbc, qtable + 64 * i, 64 * 8); + bytestream2_put_buffer(&pbc, qtable + 64 * i, 64); } /* DHT */ - put_marker(&pbc, DHT); - flush_put_bits(&pbc); - dht_size_ptr = put_bits_ptr(&pbc); - put_bits(&pbc, 16, 0); + jpeg_put_marker(&pbc, DHT); + dht_size_ptr = pbc.buffer; + bytestream2_put_be16(&pbc, 0); dht_size = 2; dht_size += jpeg_create_huffman_table(&pbc, 0, 0,avpriv_mjpeg_bits_dc_luminance, @@ -154,41 +159,38 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, AV_WB16(dht_size_ptr, dht_size); /* SOF0 */ - put_marker(&pbc, SOF0); - put_bits(&pbc, 16, 17); - put_bits(&pbc, 8, 8); - put_bits(&pbc, 16, h); - put_bits(&pbc, 16, w); - put_bits(&pbc, 8, 3); - put_bits(&pbc, 8, 1); - put_bits(&pbc, 8, type ? 34 : 33); - put_bits(&pbc, 8, 0); - put_bits(&pbc, 8, 2); - put_bits(&pbc, 8, 17); - put_bits(&pbc, 8, nb_qtable == 2 ? 1 : 0); - put_bits(&pbc, 8, 3); - put_bits(&pbc, 8, 17); - put_bits(&pbc, 8, nb_qtable == 2 ? 1 : 0); + jpeg_put_marker(&pbc, SOF0); + bytestream2_put_be16(&pbc, 17); + bytestream2_put_byte(&pbc, 8); + bytestream2_put_be16(&pbc, h); + bytestream2_put_be16(&pbc, w); + bytestream2_put_byte(&pbc, 3); + bytestream2_put_byte(&pbc, 1); + bytestream2_put_byte(&pbc, type ? 34 : 33); + bytestream2_put_byte(&pbc, 0); + bytestream2_put_byte(&pbc, 2); + bytestream2_put_byte(&pbc, 17); + bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); + bytestream2_put_byte(&pbc, 3); + bytestream2_put_byte(&pbc, 17); + bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* SOS */ - put_marker(&pbc, SOS); - put_bits(&pbc, 16, 12); - put_bits(&pbc, 8, 3); - put_bits(&pbc, 8, 1); - put_bits(&pbc, 8, 0); - put_bits(&pbc, 8, 2); - put_bits(&pbc, 8, 17); - put_bits(&pbc, 8, 3); - put_bits(&pbc, 8, 17); - put_bits(&pbc, 8, 0); - put_bits(&pbc, 8, 63); - put_bits(&pbc, 8, 0); - - /* Fill the buffer. */ - flush_put_bits(&pbc); + jpeg_put_marker(&pbc, SOS); + bytestream2_put_be16(&pbc, 12); + bytestream2_put_byte(&pbc, 3); + bytestream2_put_byte(&pbc, 1); + bytestream2_put_byte(&pbc, 0); + bytestream2_put_byte(&pbc, 2); + bytestream2_put_byte(&pbc, 17); + bytestream2_put_byte(&pbc, 3); + bytestream2_put_byte(&pbc, 17); + bytestream2_put_byte(&pbc, 0); + bytestream2_put_byte(&pbc, 63); + bytestream2_put_byte(&pbc, 0); /* Return the length in bytes of the JPEG header. */ - return put_bits_count(&pbc) / 8; + return bytestream2_tell_p(&pbc); } static void create_default_qtables(uint8_t *qtables, uint8_t q) -- cgit v1.2.3 From c64d2a63df5d7cd309c184bd0bd33dd2cb1259b1 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 12:46:44 +0300 Subject: rtpdec_jpeg: Don't use a bitstream writer for the EOI marker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 4f52c31b9f..4d8523dcb2 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -334,13 +334,9 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, if (flags & RTP_FLAG_MARKER) { /* End of JPEG data packet. */ - PutBitContext pbc; - uint8_t buf[2]; + uint8_t buf[2] = { 0xff, EOI }; /* Put EOI marker. */ - init_put_bits(&pbc, buf, sizeof(buf)); - put_marker(&pbc, EOI); - flush_put_bits(&pbc); avio_write(jpeg->frame, buf, sizeof(buf)); /* Prepare the JPEG packet. */ -- cgit v1.2.3 From 31adff08a14b7cd3f4097a4f912108cd64472069 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 12:52:55 +0300 Subject: rtpdec_jpeg: Clarify where the subsampling magic numbers come from MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Write out the numbers the way they are constructed, not just the final values. Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 4d8523dcb2..20bb356aec 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -166,13 +166,13 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, bytestream2_put_be16(&pbc, w); bytestream2_put_byte(&pbc, 3); bytestream2_put_byte(&pbc, 1); - bytestream2_put_byte(&pbc, type ? 34 : 33); + bytestream2_put_byte(&pbc, (2 << 4) | (type ? 2 : 1)); /* hsample/vsample */ bytestream2_put_byte(&pbc, 0); bytestream2_put_byte(&pbc, 2); - bytestream2_put_byte(&pbc, 17); + bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */ bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); bytestream2_put_byte(&pbc, 3); - bytestream2_put_byte(&pbc, 17); + bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */ bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* SOS */ -- cgit v1.2.3 From cbaa9eeda3c2ca8532b8bf69c9979f30284414ff Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 12:54:06 +0300 Subject: rtpdec_jpeg: Add more comments about the fields in the SOF0 section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 20bb356aec..b1361cd164 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -160,20 +160,20 @@ static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w, /* SOF0 */ jpeg_put_marker(&pbc, SOF0); - bytestream2_put_be16(&pbc, 17); - bytestream2_put_byte(&pbc, 8); + bytestream2_put_be16(&pbc, 17); /* size */ + bytestream2_put_byte(&pbc, 8); /* bits per component */ bytestream2_put_be16(&pbc, h); bytestream2_put_be16(&pbc, w); - bytestream2_put_byte(&pbc, 3); - bytestream2_put_byte(&pbc, 1); + bytestream2_put_byte(&pbc, 3); /* number of components */ + bytestream2_put_byte(&pbc, 1); /* component number */ bytestream2_put_byte(&pbc, (2 << 4) | (type ? 2 : 1)); /* hsample/vsample */ - bytestream2_put_byte(&pbc, 0); - bytestream2_put_byte(&pbc, 2); + bytestream2_put_byte(&pbc, 0); /* matrix number */ + bytestream2_put_byte(&pbc, 2); /* component number */ bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */ - bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); - bytestream2_put_byte(&pbc, 3); + bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* matrix number */ + bytestream2_put_byte(&pbc, 3); /* component number */ bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */ - bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); + bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* matrix number */ /* SOS */ jpeg_put_marker(&pbc, SOS); -- cgit v1.2.3 From a252649059b7dd1fa05e27bd6a14b5a08436456a Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 14:43:10 +0300 Subject: rtpdec_jpeg: Simplify the calculation of the number of qtables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index b1361cd164..463bf432e2 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -303,7 +303,7 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, * interchange format. */ jpeg->hdr_size = jpeg_create_header(hdr, sizeof(hdr), type, width, height, qtables, - qtable_len > 64 ? 2 : 1); + qtable_len / 64); /* Copy JPEG header to frame buffer. */ avio_write(jpeg->frame, hdr, jpeg->hdr_size); -- cgit v1.2.3 From a218deb856e7352b16e5aa3013a2b3fcdd0e3d2f Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 14:29:54 +0300 Subject: rtpdec_jpeg: Store and reuse old qtables for q values 128-254 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 463bf432e2..9dd5f68764 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -32,6 +32,8 @@ struct PayloadContext { AVIOContext *frame; ///< current frame buffer uint32_t timestamp; ///< current frame timestamp int hdr_size; ///< size of the current frame header + uint8_t qtables[128][128]; + uint8_t qtables_len[128]; }; static const uint8_t default_quantizers[128] = { @@ -267,12 +269,6 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, if (precision) av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n"); - if (q == 255 && qtable_len == 0) { - av_log(ctx, AV_LOG_ERROR, - "Invalid RTP/JPEG packet. Quantization tables not found.\n"); - return AVERROR_INVALIDDATA; - } - if (qtable_len > 0) { if (len < qtable_len) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); @@ -281,6 +277,31 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, qtables = buf; buf += qtable_len; len -= qtable_len; + if (q < 255) { + if (jpeg->qtables_len[q - 128] && + (jpeg->qtables_len[q - 128] != qtable_len || + memcmp(qtables, &jpeg->qtables[q - 128][0], qtable_len))) { + av_log(ctx, AV_LOG_WARNING, + "Quantization tables for q=%d changed\n", q); + } else if (!jpeg->qtables_len[q - 128] && qtable_len <= 128) { + memcpy(&jpeg->qtables[q - 128][0], qtables, + qtable_len); + jpeg->qtables_len[q - 128] = qtable_len; + } + } + } else { + if (q == 255) { + av_log(ctx, AV_LOG_ERROR, + "Invalid RTP/JPEG packet. Quantization tables not found.\n"); + return AVERROR_INVALIDDATA; + } + if (!jpeg->qtables_len[q - 128]) { + av_log(ctx, AV_LOG_ERROR, + "No quantization tables known for q=%d yet.\n", q); + return AVERROR_INVALIDDATA; + } + qtables = &jpeg->qtables[q - 128][0]; + qtable_len = jpeg->qtables_len[q - 128]; } } -- cgit v1.2.3 From 1de9317bd08d71b6b988a8a64de18f4c2f98e031 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 14:39:58 +0300 Subject: rtpdec_jpeg: Fold the default qtables case into an existing if statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 9dd5f68764..3f47e71bd3 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -303,6 +303,10 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, qtables = &jpeg->qtables[q - 128][0]; qtable_len = jpeg->qtables_len[q - 128]; } + } else { /* q <= 127 */ + create_default_qtables(new_qtables, q); + qtables = new_qtables; + qtable_len = sizeof(new_qtables); } /* Skip the current frame in case of the end packet @@ -313,12 +317,6 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, return ret; jpeg->timestamp = *timestamp; - if (!qtables) { - create_default_qtables(new_qtables, q); - qtables = new_qtables; - qtable_len = sizeof(new_qtables); - } - /* Generate a frame and scan headers that can be prepended to the * RTP/JPEG data payload to produce a JPEG compressed image in * interchange format. */ -- cgit v1.2.3 From 1743938df10dd888484f964d5af8fd3957d26809 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 14:41:42 +0300 Subject: rtpdec_jpeg: Disallow using the reserved q values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 3f47e71bd3..3f53887798 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -304,6 +304,10 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, qtable_len = jpeg->qtables_len[q - 128]; } } else { /* q <= 127 */ + if (q == 0 || q > 99) { + av_log(ctx, AV_LOG_ERROR, "Reserved q value %d\n", q); + return AVERROR_INVALIDDATA; + } create_default_qtables(new_qtables, q); qtables = new_qtables; qtable_len = sizeof(new_qtables); -- cgit v1.2.3 From c3bcd22ed3f843f7240fa190df8f3daa2081290f Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 11 Sep 2012 14:42:22 +0300 Subject: rtpdec_jpeg: Error out on other unsupported type values as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec_jpeg.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libavformat/rtpdec_jpeg.c') diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 3f53887798..944758d4fc 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -246,6 +246,10 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, "Unimplemented RTP/JPEG restart marker header.\n"); return AVERROR_PATCHWELCOME; } + if (type > 1) { + av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG type %d\n", type); + return AVERROR_PATCHWELCOME; + } /* Parse the quantization table header. */ if (off == 0) { -- cgit v1.2.3