Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 "libavutil/intreadwrite.h"
  25. #include "rtpenc.h"
  26.  
  27. void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size)
  28. {
  29.     RTPMuxContext *s = s1->priv_data;
  30.     const uint8_t *qtables = NULL;
  31.     int nb_qtables = 0;
  32.     uint8_t type = 1; /* default pixel format is AV_PIX_FMT_YUVJ420P */
  33.     uint8_t w, h;
  34.     uint8_t *p;
  35.     int off = 0; /* fragment offset of the current JPEG frame */
  36.     int len;
  37.     int i;
  38.  
  39.     s->buf_ptr   = s->buf;
  40.     s->timestamp = s->cur_timestamp;
  41.  
  42.     /* convert video pixel dimensions from pixels to blocks */
  43.     w = s1->streams[0]->codec->width  >> 3;
  44.     h = s1->streams[0]->codec->height >> 3;
  45.  
  46.     /* check if pixel format is not the normal 420 case */
  47.     if (s1->streams[0]->codec->pix_fmt == AV_PIX_FMT_YUVJ422P) {
  48.         type = 0;
  49.     } else if (s1->streams[0]->codec->pix_fmt == AV_PIX_FMT_YUVJ420P) {
  50.         type = 1;
  51.     } else {
  52.         av_log(s1, AV_LOG_ERROR, "Unsupported pixel format\n");
  53.         return;
  54.     }
  55.  
  56.     /* preparse the header for getting some infos */
  57.     for (i = 0; i < size; i++) {
  58.         if (buf[i] != 0xff)
  59.             continue;
  60.  
  61.         if (buf[i + 1] == DQT) {
  62.             if (buf[i + 4])
  63.                 av_log(s1, AV_LOG_WARNING,
  64.                        "Only 8-bit precision is supported.\n");
  65.  
  66.             /* a quantization table is 64 bytes long */
  67.             nb_qtables = AV_RB16(&buf[i + 2]) / 65;
  68.             if (i + 4 + nb_qtables * 65 > size) {
  69.                 av_log(s1, AV_LOG_ERROR, "Too short JPEG header. Aborted!\n");
  70.                 return;
  71.             }
  72.  
  73.             qtables = &buf[i + 4];
  74.         } else if (buf[i + 1] == SOF0) {
  75.             if (buf[i + 14] != 17 || buf[i + 17] != 17) {
  76.                 av_log(s1, AV_LOG_ERROR,
  77.                        "Only 1x1 chroma blocks are supported. Aborted!\n");
  78.                 return;
  79.             }
  80.         } else if (buf[i + 1] == SOS) {
  81.             /* SOS is last marker in the header */
  82.             i += AV_RB16(&buf[i + 2]) + 2;
  83.             break;
  84.         }
  85.     }
  86.  
  87.     /* skip JPEG header */
  88.     buf  += i;
  89.     size -= i;
  90.  
  91.     for (i = size - 2; i >= 0; i--) {
  92.         if (buf[i] == 0xff && buf[i + 1] == EOI) {
  93.             /* Remove the EOI marker */
  94.             size = i;
  95.             break;
  96.         }
  97.     }
  98.  
  99.     p = s->buf_ptr;
  100.     while (size > 0) {
  101.         int hdr_size = 8;
  102.  
  103.         if (off == 0 && nb_qtables)
  104.             hdr_size += 4 + 64 * nb_qtables;
  105.  
  106.         /* payload max in one packet */
  107.         len = FFMIN(size, s->max_payload_size - hdr_size);
  108.  
  109.         /* set main header */
  110.         bytestream_put_byte(&p, 0);
  111.         bytestream_put_be24(&p, off);
  112.         bytestream_put_byte(&p, type);
  113.         bytestream_put_byte(&p, 255);
  114.         bytestream_put_byte(&p, w);
  115.         bytestream_put_byte(&p, h);
  116.  
  117.         if (off == 0 && nb_qtables) {
  118.             /* set quantization tables header */
  119.             bytestream_put_byte(&p, 0);
  120.             bytestream_put_byte(&p, 0);
  121.             bytestream_put_be16(&p, 64 * nb_qtables);
  122.  
  123.             for (i = 0; i < nb_qtables; i++)
  124.                 bytestream_put_buffer(&p, &qtables[65 * i + 1], 64);
  125.         }
  126.  
  127.         /* copy payload data */
  128.         memcpy(p, buf, len);
  129.  
  130.         /* marker bit is last packet in frame */
  131.         ff_rtp_send_data(s1, s->buf, len + hdr_size, size == len);
  132.  
  133.         buf  += len;
  134.         size -= len;
  135.         off  += len;
  136.         p     = s->buf;
  137.     }
  138. }
  139.