LCOV - code coverage report
Current view: top level - libavformat - rtpenc_h261.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 27 0.0 %
Date: 2017-12-18 13:19:42 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /*
       2             :  * RTP packetization for H.261 video (RFC 4587)
       3             :  * Copyright (c) 2014 Thomas Volkert <thomas@homer-conferencing.com>
       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 "avformat.h"
      23             : #include "rtpenc.h"
      24             : 
      25             : #define RTP_H261_HEADER_SIZE 4
      26             : 
      27           0 : static const uint8_t *find_resync_marker_reverse(const uint8_t *av_restrict start,
      28             :                                                  const uint8_t *av_restrict end)
      29             : {
      30           0 :     const uint8_t *p = end - 1;
      31           0 :     start += 1; /* Make sure we never return the original start. */
      32           0 :     for (; p > start; p--) {
      33           0 :         if (p[0] == 0 && p[1] == 1)
      34           0 :             return p;
      35             :     }
      36           0 :     return end;
      37             : }
      38             : 
      39           0 : void ff_rtp_send_h261(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size)
      40             : {
      41             :     int cur_frame_size;
      42             :     int last_packet_of_frame;
      43           0 :     RTPMuxContext *rtp_ctx = ctx->priv_data;
      44             : 
      45             :     /* use the default 90 KHz time stamp */
      46           0 :     rtp_ctx->timestamp = rtp_ctx->cur_timestamp;
      47             : 
      48             :     /* continue as long as not all frame data is processed */
      49           0 :     while (frame_size > 0) {
      50             :         /*
      51             :          * encode the H.261 payload header according to section 4.1 of RFC 4587:
      52             :          * (uses 4 bytes between RTP header and H.261 stream per packet)
      53             :          *
      54             :          *    0                   1                   2                   3
      55             :          *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      56             :          *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      57             :          *   |SBIT |EBIT |I|V| GOBN  |   MBAP  |  QUANT  |  HMVD   |  VMVD   |
      58             :          *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      59             :          *
      60             :          *      Start bit position (SBIT): 3 bits
      61             :          *      End bit position (EBIT): 3 bits
      62             :          *      INTRA-frame encoded data (I): 1 bit
      63             :          *      Motion Vector flag (V): 1 bit
      64             :          *      GOB number (GOBN): 4 bits
      65             :          *      Macroblock address predictor (MBAP): 5 bits
      66             :          *      Quantizer (QUANT): 5 bits
      67             :          *      Horizontal motion vector data (HMVD): 5 bits
      68             :          *      Vertical motion vector data (VMVD): 5 bits
      69             :          */
      70           0 :         rtp_ctx->buf[0] = 1; /* sbit=0, ebit=0, i=0, v=1 */
      71           0 :         rtp_ctx->buf[1] = 0; /* gobn=0, mbap=0 */
      72           0 :         rtp_ctx->buf[2] = 0; /* quant=0, hmvd=5 */
      73           0 :         rtp_ctx->buf[3] = 0; /* vmvd=0 */
      74           0 :         if (frame_size < 2 || frame_buf[0] != 0 || frame_buf[1] != 1) {
      75             :             /* A full, correct fix for this would be to make the H.261 encoder
      76             :              * support inserting extra GOB headers (triggered by setting e.g.
      77             :              * "-ps 1"), and including information about macroblock boundaries
      78             :              * (such as for h263_rfc2190). */
      79           0 :             av_log(ctx, AV_LOG_WARNING,
      80             :                    "RTP/H.261 packet not cut at a GOB boundary, not signaled correctly\n");
      81             :         }
      82             : 
      83           0 :         cur_frame_size = FFMIN(rtp_ctx->max_payload_size - RTP_H261_HEADER_SIZE, frame_size);
      84             : 
      85             :         /* look for a better place to split the frame into packets */
      86           0 :         if (cur_frame_size < frame_size) {
      87           0 :             const uint8_t *packet_end = find_resync_marker_reverse(frame_buf,
      88             :                                                                    frame_buf + cur_frame_size);
      89           0 :             cur_frame_size = packet_end - frame_buf;
      90             :         }
      91             : 
      92             :         /* calculate the "marker" bit for the RTP header */
      93           0 :         last_packet_of_frame = cur_frame_size == frame_size;
      94             : 
      95             :         /* complete and send RTP packet */
      96           0 :         memcpy(&rtp_ctx->buf[RTP_H261_HEADER_SIZE], frame_buf, cur_frame_size);
      97           0 :         ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_H261_HEADER_SIZE + cur_frame_size, last_packet_of_frame);
      98             : 
      99           0 :         frame_buf  += cur_frame_size;
     100           0 :         frame_size -= cur_frame_size;
     101             :     }
     102           0 : }

Generated by: LCOV version 1.13