LCOV - code coverage report
Current view: top level - libavformat - rtpenc_jpeg.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 134 0.0 %
Date: 2017-12-11 04:34:20 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /*
       2             :  * RTP JPEG-compressed video Packetizer, RFC 2435
       3             :  * Copyright (c) 2012 Samuel Pitoiset
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include "libavcodec/bytestream.h"
      23             : #include "libavcodec/mjpeg.h"
      24             : #include "libavcodec/jpegtables.h"
      25             : #include "libavutil/intreadwrite.h"
      26             : #include "rtpenc.h"
      27             : 
      28           0 : void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
      29             : {
      30           0 :     RTPMuxContext *s = s1->priv_data;
      31           0 :     const uint8_t *qtables[4] = { NULL };
      32           0 :     int nb_qtables = 0;
      33             :     uint8_t type;
      34             :     uint8_t w, h;
      35             :     uint8_t *p;
      36           0 :     int off = 0; /* fragment offset of the current JPEG frame */
      37             :     int len;
      38             :     int i;
      39           0 :     int default_huffman_tables = 0;
      40             : 
      41           0 :     s->buf_ptr   = s->buf;
      42           0 :     s->timestamp = s->cur_timestamp;
      43             : 
      44             :     /* convert video pixel dimensions from pixels to blocks */
      45           0 :     w = AV_CEIL_RSHIFT(s1->streams[0]->codecpar->width, 3);
      46           0 :     h = AV_CEIL_RSHIFT(s1->streams[0]->codecpar->height, 3);
      47             : 
      48             :     /* get the pixel format type or fail */
      49           0 :     if (s1->streams[0]->codecpar->format == AV_PIX_FMT_YUVJ422P ||
      50           0 :         (s1->streams[0]->codecpar->color_range == AVCOL_RANGE_JPEG &&
      51           0 :          s1->streams[0]->codecpar->format == AV_PIX_FMT_YUV422P)) {
      52           0 :         type = 0;
      53           0 :     } else if (s1->streams[0]->codecpar->format == AV_PIX_FMT_YUVJ420P ||
      54           0 :                (s1->streams[0]->codecpar->color_range == AVCOL_RANGE_JPEG &&
      55           0 :                 s1->streams[0]->codecpar->format == AV_PIX_FMT_YUV420P)) {
      56           0 :         type = 1;
      57             :     } else {
      58           0 :         av_log(s1, AV_LOG_ERROR, "Unsupported pixel format\n");
      59           0 :         return;
      60             :     }
      61             : 
      62             :     /* preparse the header for getting some info */
      63           0 :     for (i = 0; i < size; i++) {
      64           0 :         if (buf[i] != 0xff)
      65           0 :             continue;
      66             : 
      67           0 :         if (buf[i + 1] == DQT) {
      68             :             int tables, j;
      69           0 :             if (buf[i + 4] & 0xF0)
      70           0 :                 av_log(s1, AV_LOG_WARNING,
      71             :                        "Only 8-bit precision is supported.\n");
      72             : 
      73             :             /* a quantization table is 64 bytes long */
      74           0 :             tables = AV_RB16(&buf[i + 2]) / 65;
      75           0 :             if (i + 5 + tables * 65 > size) {
      76           0 :                 av_log(s1, AV_LOG_ERROR, "Too short JPEG header. Aborted!\n");
      77           0 :                 return;
      78             :             }
      79           0 :             if (nb_qtables + tables > 4) {
      80           0 :                 av_log(s1, AV_LOG_ERROR, "Invalid number of quantisation tables\n");
      81           0 :                 return;
      82             :             }
      83             : 
      84           0 :             for (j = 0; j < tables; j++)
      85           0 :                 qtables[nb_qtables + j] = buf + i + 5 + j * 65;
      86           0 :             nb_qtables += tables;
      87           0 :         } else if (buf[i + 1] == SOF0) {
      88           0 :             if (buf[i + 14] != 17 || buf[i + 17] != 17) {
      89           0 :                 av_log(s1, AV_LOG_ERROR,
      90             :                        "Only 1x1 chroma blocks are supported. Aborted!\n");
      91           0 :                 return;
      92             :             }
      93           0 :         } else if (buf[i + 1] == DHT) {
      94           0 :             int dht_size = AV_RB16(&buf[i + 2]);
      95           0 :             default_huffman_tables |= 1 << 4;
      96           0 :             i += 3;
      97           0 :             dht_size -= 2;
      98           0 :             if (i + dht_size >= size)
      99           0 :                 continue;
     100           0 :             while (dht_size > 0)
     101           0 :                 switch (buf[i + 1]) {
     102           0 :                 case 0x00:
     103           0 :                     if (   dht_size >= 29
     104           0 :                         && !memcmp(buf + i +  2, avpriv_mjpeg_bits_dc_luminance + 1, 16)
     105           0 :                         && !memcmp(buf + i + 18, avpriv_mjpeg_val_dc, 12)) {
     106           0 :                         default_huffman_tables |= 1;
     107           0 :                         i += 29;
     108           0 :                         dht_size -= 29;
     109             :                     } else {
     110           0 :                         i += dht_size;
     111           0 :                         dht_size = 0;
     112             :                     }
     113           0 :                     break;
     114           0 :                 case 0x01:
     115           0 :                     if (   dht_size >= 29
     116           0 :                         && !memcmp(buf + i +  2, avpriv_mjpeg_bits_dc_chrominance + 1, 16)
     117           0 :                         && !memcmp(buf + i + 18, avpriv_mjpeg_val_dc, 12)) {
     118           0 :                         default_huffman_tables |= 1 << 1;
     119           0 :                         i += 29;
     120           0 :                         dht_size -= 29;
     121             :                     } else {
     122           0 :                         i += dht_size;
     123           0 :                         dht_size = 0;
     124             :                     }
     125           0 :                     break;
     126           0 :                 case 0x10:
     127           0 :                     if (   dht_size >= 179
     128           0 :                         && !memcmp(buf + i +  2, avpriv_mjpeg_bits_ac_luminance   + 1, 16)
     129           0 :                         && !memcmp(buf + i + 18, avpriv_mjpeg_val_ac_luminance, 162)) {
     130           0 :                         default_huffman_tables |= 1 << 2;
     131           0 :                         i += 179;
     132           0 :                         dht_size -= 179;
     133             :                     } else {
     134           0 :                         i += dht_size;
     135           0 :                         dht_size = 0;
     136             :                     }
     137           0 :                     break;
     138           0 :                 case 0x11:
     139           0 :                     if (   dht_size >= 179
     140           0 :                         && !memcmp(buf + i +  2, avpriv_mjpeg_bits_ac_chrominance + 1, 16)
     141           0 :                         && !memcmp(buf + i + 18, avpriv_mjpeg_val_ac_chrominance, 162)) {
     142           0 :                         default_huffman_tables |= 1 << 3;
     143           0 :                         i += 179;
     144           0 :                         dht_size -= 179;
     145             :                     } else {
     146           0 :                         i += dht_size;
     147           0 :                         dht_size = 0;
     148             :                     }
     149           0 :                     break;
     150           0 :                 default:
     151           0 :                     i += dht_size;
     152           0 :                     dht_size = 0;
     153           0 :                     continue;
     154             :             }
     155           0 :         } else if (buf[i + 1] == SOS) {
     156             :             /* SOS is last marker in the header */
     157           0 :             i += AV_RB16(&buf[i + 2]) + 2;
     158           0 :             if (i > size) {
     159           0 :                 av_log(s1, AV_LOG_ERROR,
     160             :                        "Insufficient data. Aborted!\n");
     161           0 :                 return;
     162             :             }
     163           0 :             break;
     164             :         }
     165             :     }
     166           0 :     if (default_huffman_tables && default_huffman_tables != 31) {
     167           0 :         av_log(s1, AV_LOG_ERROR,
     168             :                "RFC 2435 requires standard Huffman tables for jpeg\n");
     169           0 :         return;
     170             :     }
     171           0 :     if (nb_qtables && nb_qtables != 2)
     172           0 :         av_log(s1, AV_LOG_WARNING,
     173             :                "RFC 2435 suggests two quantization tables, %d provided\n",
     174             :                nb_qtables);
     175             : 
     176             :     /* skip JPEG header */
     177           0 :     buf  += i;
     178           0 :     size -= i;
     179             : 
     180           0 :     for (i = size - 2; i >= 0; i--) {
     181           0 :         if (buf[i] == 0xff && buf[i + 1] == EOI) {
     182             :             /* Remove the EOI marker */
     183           0 :             size = i;
     184           0 :             break;
     185             :         }
     186             :     }
     187             : 
     188           0 :     p = s->buf_ptr;
     189           0 :     while (size > 0) {
     190           0 :         int hdr_size = 8;
     191             : 
     192           0 :         if (off == 0 && nb_qtables)
     193           0 :             hdr_size += 4 + 64 * nb_qtables;
     194             : 
     195             :         /* payload max in one packet */
     196           0 :         len = FFMIN(size, s->max_payload_size - hdr_size);
     197             : 
     198             :         /* set main header */
     199           0 :         bytestream_put_byte(&p, 0);
     200           0 :         bytestream_put_be24(&p, off);
     201           0 :         bytestream_put_byte(&p, type);
     202           0 :         bytestream_put_byte(&p, 255);
     203           0 :         bytestream_put_byte(&p, w);
     204           0 :         bytestream_put_byte(&p, h);
     205             : 
     206           0 :         if (off == 0 && nb_qtables) {
     207             :             /* set quantization tables header */
     208           0 :             bytestream_put_byte(&p, 0);
     209           0 :             bytestream_put_byte(&p, 0);
     210           0 :             bytestream_put_be16(&p, 64 * nb_qtables);
     211             : 
     212           0 :             for (i = 0; i < nb_qtables; i++)
     213           0 :                 bytestream_put_buffer(&p, qtables[i], 64);
     214             :         }
     215             : 
     216             :         /* copy payload data */
     217           0 :         memcpy(p, buf, len);
     218             : 
     219             :         /* marker bit is last packet in frame */
     220           0 :         ff_rtp_send_data(s1, s->buf, len + hdr_size, size == len);
     221             : 
     222           0 :         buf  += len;
     223           0 :         size -= len;
     224           0 :         off  += len;
     225           0 :         p     = s->buf;
     226             :     }
     227             : }

Generated by: LCOV version 1.13