annotate ffmpeg/libavformat/rtpenc_h263_rfc2190.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * RTP packetization for H.263 video
yading@11 3 * Copyright (c) 2012 Martin Storsjo
yading@11 4 *
yading@11 5 * This file is part of Libav.
yading@11 6 *
yading@11 7 * Libav is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * Libav is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with Libav; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 #include "avformat.h"
yading@11 23 #include "rtpenc.h"
yading@11 24 #include "libavcodec/put_bits.h"
yading@11 25 #include "libavcodec/get_bits.h"
yading@11 26
yading@11 27 struct H263Info {
yading@11 28 int src;
yading@11 29 int i;
yading@11 30 int u;
yading@11 31 int s;
yading@11 32 int a;
yading@11 33 int pb;
yading@11 34 int tr;
yading@11 35 };
yading@11 36
yading@11 37 struct H263State {
yading@11 38 int gobn;
yading@11 39 int mba;
yading@11 40 int hmv1, vmv1, hmv2, vmv2;
yading@11 41 int quant;
yading@11 42 };
yading@11 43
yading@11 44 static void send_mode_a(AVFormatContext *s1, const struct H263Info *info,
yading@11 45 const uint8_t *buf, int len, int ebits, int m)
yading@11 46 {
yading@11 47 RTPMuxContext *s = s1->priv_data;
yading@11 48 PutBitContext pb;
yading@11 49
yading@11 50 init_put_bits(&pb, s->buf, 32);
yading@11 51 put_bits(&pb, 1, 0); /* F - 0, mode A */
yading@11 52 put_bits(&pb, 1, 0); /* P - 0, normal I/P */
yading@11 53 put_bits(&pb, 3, 0); /* SBIT - 0 bits */
yading@11 54 put_bits(&pb, 3, ebits); /* EBIT */
yading@11 55 put_bits(&pb, 3, info->src); /* SRC - source format */
yading@11 56 put_bits(&pb, 1, info->i); /* I - inter/intra */
yading@11 57 put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
yading@11 58 put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
yading@11 59 put_bits(&pb, 1, info->a); /* A - advanced prediction */
yading@11 60 put_bits(&pb, 4, 0); /* R - reserved */
yading@11 61 put_bits(&pb, 2, 0); /* DBQ - 0 */
yading@11 62 put_bits(&pb, 3, 0); /* TRB - 0 */
yading@11 63 put_bits(&pb, 8, info->tr); /* TR */
yading@11 64 flush_put_bits(&pb);
yading@11 65 memcpy(s->buf + 4, buf, len);
yading@11 66
yading@11 67 ff_rtp_send_data(s1, s->buf, len + 4, m);
yading@11 68 }
yading@11 69
yading@11 70 static void send_mode_b(AVFormatContext *s1, const struct H263Info *info,
yading@11 71 const struct H263State *state, const uint8_t *buf,
yading@11 72 int len, int sbits, int ebits, int m)
yading@11 73 {
yading@11 74 RTPMuxContext *s = s1->priv_data;
yading@11 75 PutBitContext pb;
yading@11 76
yading@11 77 init_put_bits(&pb, s->buf, 64);
yading@11 78 put_bits(&pb, 1, 1); /* F - 1, mode B */
yading@11 79 put_bits(&pb, 1, 0); /* P - 0, mode B */
yading@11 80 put_bits(&pb, 3, sbits); /* SBIT - 0 bits */
yading@11 81 put_bits(&pb, 3, ebits); /* EBIT - 0 bits */
yading@11 82 put_bits(&pb, 3, info->src); /* SRC - source format */
yading@11 83 put_bits(&pb, 5, state->quant); /* QUANT - quantizer for the first MB */
yading@11 84 put_bits(&pb, 5, state->gobn); /* GOBN - GOB number */
yading@11 85 put_bits(&pb, 9, state->mba); /* MBA - MB address */
yading@11 86 put_bits(&pb, 2, 0); /* R - reserved */
yading@11 87 put_bits(&pb, 1, info->i); /* I - inter/intra */
yading@11 88 put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
yading@11 89 put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
yading@11 90 put_bits(&pb, 1, info->a); /* A - advanced prediction */
yading@11 91 put_bits(&pb, 7, state->hmv1); /* HVM1 - horizontal motion vector 1 */
yading@11 92 put_bits(&pb, 7, state->vmv1); /* VMV1 - vertical motion vector 1 */
yading@11 93 put_bits(&pb, 7, state->hmv2); /* HVM2 - horizontal motion vector 2 */
yading@11 94 put_bits(&pb, 7, state->vmv2); /* VMV2 - vertical motion vector 2 */
yading@11 95 flush_put_bits(&pb);
yading@11 96 memcpy(s->buf + 8, buf, len);
yading@11 97
yading@11 98 ff_rtp_send_data(s1, s->buf, len + 8, m);
yading@11 99 }
yading@11 100
yading@11 101 void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size,
yading@11 102 const uint8_t *mb_info, int mb_info_size)
yading@11 103 {
yading@11 104 RTPMuxContext *s = s1->priv_data;
yading@11 105 int len, sbits = 0, ebits = 0;
yading@11 106 GetBitContext gb;
yading@11 107 struct H263Info info = { 0 };
yading@11 108 struct H263State state = { 0 };
yading@11 109 int mb_info_pos = 0, mb_info_count = mb_info_size / 12;
yading@11 110 const uint8_t *buf_base = buf;
yading@11 111
yading@11 112 s->timestamp = s->cur_timestamp;
yading@11 113
yading@11 114 init_get_bits(&gb, buf, size*8);
yading@11 115 if (get_bits(&gb, 22) == 0x20) { /* Picture Start Code */
yading@11 116 info.tr = get_bits(&gb, 8);
yading@11 117 skip_bits(&gb, 2); /* PTYPE start, H261 disambiguation */
yading@11 118 skip_bits(&gb, 3); /* Split screen, document camera, freeze picture release */
yading@11 119 info.src = get_bits(&gb, 3);
yading@11 120 info.i = get_bits(&gb, 1);
yading@11 121 info.u = get_bits(&gb, 1);
yading@11 122 info.s = get_bits(&gb, 1);
yading@11 123 info.a = get_bits(&gb, 1);
yading@11 124 info.pb = get_bits(&gb, 1);
yading@11 125 }
yading@11 126
yading@11 127 while (size > 0) {
yading@11 128 struct H263State packet_start_state = state;
yading@11 129 len = FFMIN(s->max_payload_size - 8, size);
yading@11 130
yading@11 131 /* Look for a better place to split the frame into packets. */
yading@11 132 if (len < size) {
yading@11 133 const uint8_t *end = ff_h263_find_resync_marker_reverse(buf,
yading@11 134 buf + len);
yading@11 135 len = end - buf;
yading@11 136 if (len == s->max_payload_size - 8) {
yading@11 137 /* Skip mb info prior to the start of the current ptr */
yading@11 138 while (mb_info_pos < mb_info_count) {
yading@11 139 uint32_t pos = AV_RL32(&mb_info[12*mb_info_pos])/8;
yading@11 140 if (pos >= buf - buf_base)
yading@11 141 break;
yading@11 142 mb_info_pos++;
yading@11 143 }
yading@11 144 /* Find the first mb info past the end pointer */
yading@11 145 while (mb_info_pos + 1 < mb_info_count) {
yading@11 146 uint32_t pos = AV_RL32(&mb_info[12*(mb_info_pos + 1)])/8;
yading@11 147 if (pos >= end - buf_base)
yading@11 148 break;
yading@11 149 mb_info_pos++;
yading@11 150 }
yading@11 151 if (mb_info_pos < mb_info_count) {
yading@11 152 const uint8_t *ptr = &mb_info[12*mb_info_pos];
yading@11 153 uint32_t bit_pos = AV_RL32(ptr);
yading@11 154 uint32_t pos = (bit_pos + 7)/8;
yading@11 155 if (pos <= end - buf_base) {
yading@11 156 state.quant = ptr[4];
yading@11 157 state.gobn = ptr[5];
yading@11 158 state.mba = AV_RL16(&ptr[6]);
yading@11 159 state.hmv1 = (int8_t) ptr[8];
yading@11 160 state.vmv1 = (int8_t) ptr[9];
yading@11 161 state.hmv2 = (int8_t) ptr[10];
yading@11 162 state.vmv2 = (int8_t) ptr[11];
yading@11 163 ebits = 8 * pos - bit_pos;
yading@11 164 len = pos - (buf - buf_base);
yading@11 165 mb_info_pos++;
yading@11 166 } else {
yading@11 167 av_log(s1, AV_LOG_ERROR,
yading@11 168 "Unable to split H263 packet, use -mb_info %d "
yading@11 169 "or lower.\n", s->max_payload_size - 8);
yading@11 170 }
yading@11 171 } else {
yading@11 172 av_log(s1, AV_LOG_ERROR, "Unable to split H263 packet, "
yading@11 173 "use -mb_info %d or -ps 1.\n",
yading@11 174 s->max_payload_size - 8);
yading@11 175 }
yading@11 176 }
yading@11 177 }
yading@11 178
yading@11 179 if (size > 2 && !buf[0] && !buf[1])
yading@11 180 send_mode_a(s1, &info, buf, len, ebits, len == size);
yading@11 181 else
yading@11 182 send_mode_b(s1, &info, &packet_start_state, buf, len, sbits,
yading@11 183 ebits, len == size);
yading@11 184
yading@11 185 if (ebits) {
yading@11 186 sbits = 8 - ebits;
yading@11 187 len--;
yading@11 188 } else {
yading@11 189 sbits = 0;
yading@11 190 }
yading@11 191 buf += len;
yading@11 192 size -= len;
yading@11 193 ebits = 0;
yading@11 194 }
yading@11 195 }