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

          Line data    Source code
       1             : /*
       2             :  * RTP packetization for H.263 video
       3             :  * Copyright (c) 2012 Martin Storsjo
       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             : #include "libavcodec/put_bits.h"
      25             : #include "libavcodec/get_bits.h"
      26             : 
      27             : struct H263Info {
      28             :     int src;
      29             :     int i;
      30             :     int u;
      31             :     int s;
      32             :     int a;
      33             :     int pb;
      34             :     int tr;
      35             : };
      36             : 
      37             : struct H263State {
      38             :     int gobn;
      39             :     int mba;
      40             :     int hmv1, vmv1, hmv2, vmv2;
      41             :     int quant;
      42             : };
      43             : 
      44           0 : static void send_mode_a(AVFormatContext *s1, const struct H263Info *info,
      45             :                         const uint8_t *buf, int len, int ebits, int m)
      46             : {
      47           0 :     RTPMuxContext *s = s1->priv_data;
      48             :     PutBitContext pb;
      49             : 
      50           0 :     init_put_bits(&pb, s->buf, 32);
      51           0 :     put_bits(&pb, 1, 0); /* F - 0, mode A */
      52           0 :     put_bits(&pb, 1, 0); /* P - 0, normal I/P */
      53           0 :     put_bits(&pb, 3, 0); /* SBIT - 0 bits */
      54           0 :     put_bits(&pb, 3, ebits); /* EBIT */
      55           0 :     put_bits(&pb, 3, info->src); /* SRC - source format */
      56           0 :     put_bits(&pb, 1, info->i); /* I - inter/intra */
      57           0 :     put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
      58           0 :     put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
      59           0 :     put_bits(&pb, 1, info->a); /* A - advanced prediction */
      60           0 :     put_bits(&pb, 4, 0); /* R - reserved */
      61           0 :     put_bits(&pb, 2, 0); /* DBQ - 0 */
      62           0 :     put_bits(&pb, 3, 0); /* TRB - 0 */
      63           0 :     put_bits(&pb, 8, info->tr); /* TR */
      64           0 :     flush_put_bits(&pb);
      65           0 :     memcpy(s->buf + 4, buf, len);
      66             : 
      67           0 :     ff_rtp_send_data(s1, s->buf, len + 4, m);
      68           0 : }
      69             : 
      70           0 : static void send_mode_b(AVFormatContext *s1, const struct H263Info *info,
      71             :                         const struct H263State *state, const uint8_t *buf,
      72             :                         int len, int sbits, int ebits, int m)
      73             : {
      74           0 :     RTPMuxContext *s = s1->priv_data;
      75             :     PutBitContext pb;
      76             : 
      77           0 :     init_put_bits(&pb, s->buf, 64);
      78           0 :     put_bits(&pb, 1, 1); /* F - 1, mode B */
      79           0 :     put_bits(&pb, 1, 0); /* P - 0, mode B */
      80           0 :     put_bits(&pb, 3, sbits); /* SBIT - 0 bits */
      81           0 :     put_bits(&pb, 3, ebits); /* EBIT - 0 bits */
      82           0 :     put_bits(&pb, 3, info->src); /* SRC - source format */
      83           0 :     put_bits(&pb, 5, state->quant); /* QUANT - quantizer for the first MB */
      84           0 :     put_bits(&pb, 5, state->gobn); /* GOBN - GOB number */
      85           0 :     put_bits(&pb, 9, state->mba); /* MBA - MB address */
      86           0 :     put_bits(&pb, 2, 0); /* R - reserved */
      87           0 :     put_bits(&pb, 1, info->i); /* I - inter/intra */
      88           0 :     put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
      89           0 :     put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
      90           0 :     put_bits(&pb, 1, info->a); /* A - advanced prediction */
      91           0 :     put_bits(&pb, 7, state->hmv1); /* HVM1 - horizontal motion vector 1 */
      92           0 :     put_bits(&pb, 7, state->vmv1); /* VMV1 - vertical motion vector 1 */
      93           0 :     put_bits(&pb, 7, state->hmv2); /* HVM2 - horizontal motion vector 2 */
      94           0 :     put_bits(&pb, 7, state->vmv2); /* VMV2 - vertical motion vector 2 */
      95           0 :     flush_put_bits(&pb);
      96           0 :     memcpy(s->buf + 8, buf, len);
      97             : 
      98           0 :     ff_rtp_send_data(s1, s->buf, len + 8, m);
      99           0 : }
     100             : 
     101           0 : void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size,
     102             :                               const uint8_t *mb_info, int mb_info_size)
     103             : {
     104           0 :     RTPMuxContext *s = s1->priv_data;
     105           0 :     int len, sbits = 0, ebits = 0;
     106             :     GetBitContext gb;
     107           0 :     struct H263Info info = { 0 };
     108           0 :     struct H263State state = { 0 };
     109           0 :     int mb_info_pos = 0, mb_info_count = mb_info_size / 12;
     110           0 :     const uint8_t *buf_base = buf;
     111             : 
     112           0 :     s->timestamp = s->cur_timestamp;
     113             : 
     114           0 :     init_get_bits(&gb, buf, size*8);
     115           0 :     if (get_bits(&gb, 22) == 0x20) { /* Picture Start Code */
     116           0 :         info.tr  = get_bits(&gb, 8);
     117           0 :         skip_bits(&gb, 2); /* PTYPE start, H.261 disambiguation */
     118           0 :         skip_bits(&gb, 3); /* Split screen, document camera, freeze picture release */
     119           0 :         info.src = get_bits(&gb, 3);
     120           0 :         info.i   = get_bits(&gb, 1);
     121           0 :         info.u   = get_bits(&gb, 1);
     122           0 :         info.s   = get_bits(&gb, 1);
     123           0 :         info.a   = get_bits(&gb, 1);
     124           0 :         info.pb  = get_bits(&gb, 1);
     125             :     }
     126             : 
     127           0 :     while (size > 0) {
     128           0 :         struct H263State packet_start_state = state;
     129           0 :         len = FFMIN(s->max_payload_size - 8, size);
     130             : 
     131             :         /* Look for a better place to split the frame into packets. */
     132           0 :         if (len < size) {
     133           0 :             const uint8_t *end = ff_h263_find_resync_marker_reverse(buf,
     134             :                                                                     buf + len);
     135           0 :             len = end - buf;
     136           0 :             if (len == s->max_payload_size - 8) {
     137             :                 /* Skip mb info prior to the start of the current ptr */
     138           0 :                 while (mb_info_pos < mb_info_count) {
     139           0 :                     uint32_t pos = AV_RL32(&mb_info[12*mb_info_pos])/8;
     140           0 :                     if (pos >= buf - buf_base)
     141           0 :                         break;
     142           0 :                     mb_info_pos++;
     143             :                 }
     144             :                 /* Find the first mb info past the end pointer */
     145           0 :                 while (mb_info_pos + 1 < mb_info_count) {
     146           0 :                     uint32_t pos = AV_RL32(&mb_info[12*(mb_info_pos + 1)])/8;
     147           0 :                     if (pos >= end - buf_base)
     148           0 :                         break;
     149           0 :                     mb_info_pos++;
     150             :                 }
     151           0 :                 if (mb_info_pos < mb_info_count) {
     152           0 :                     const uint8_t *ptr = &mb_info[12*mb_info_pos];
     153             :                     /* get position in bits in the input packet at which the next info block should be used */
     154           0 :                     uint32_t bit_pos = AV_RL32(ptr);
     155             :                     /* get position in bytes */
     156           0 :                     uint32_t pos_next_mb_info = (bit_pos + 7)/8;
     157             :                     /* check if data from the next MB info block should be used */
     158           0 :                     if (pos_next_mb_info <= end - buf_base) {
     159           0 :                         state.quant = ptr[4];
     160           0 :                         state.gobn  = ptr[5];
     161           0 :                         state.mba   = AV_RL16(&ptr[6]);
     162           0 :                         state.hmv1  = (int8_t) ptr[8];
     163           0 :                         state.vmv1  = (int8_t) ptr[9];
     164           0 :                         state.hmv2  = (int8_t) ptr[10];
     165           0 :                         state.vmv2  = (int8_t) ptr[11];
     166           0 :                         ebits = 8 * pos_next_mb_info - bit_pos;
     167           0 :                         len   = pos_next_mb_info - (buf - buf_base);
     168           0 :                         mb_info_pos++;
     169             :                     }
     170             :                 } else {
     171           0 :                     av_log(s1, AV_LOG_ERROR, "Unable to split H.263 packet, "
     172             :                            "use -mb_info %d or -ps 1.\n",
     173           0 :                            s->max_payload_size - 8);
     174             :                 }
     175             :             }
     176             :         }
     177             : 
     178           0 :         if (size > 2 && !buf[0] && !buf[1])
     179           0 :             send_mode_a(s1, &info, buf, len, ebits, len == size);
     180             :         else
     181           0 :             send_mode_b(s1, &info, &packet_start_state, buf, len, sbits,
     182             :                         ebits, len == size);
     183             : 
     184           0 :         if (ebits) {
     185           0 :             sbits = 8 - ebits;
     186           0 :             len--;
     187             :         } else {
     188           0 :             sbits = 0;
     189             :         }
     190           0 :         buf  += len;
     191           0 :         size -= len;
     192           0 :         ebits = 0;
     193             :     }
     194           0 : }

Generated by: LCOV version 1.13