1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * RTP H.263 Depacketizer, RFC 2190 3cabdff1aSopenharmony_ci * Copyright (c) 2012 Martin Storsjo 4cabdff1aSopenharmony_ci * Based on the GStreamer H.263 Depayloder: 5cabdff1aSopenharmony_ci * Copyright 2005 Wim Taymans 6cabdff1aSopenharmony_ci * Copyright 2007 Edward Hervey 7cabdff1aSopenharmony_ci * Copyright 2007 Nokia Corporation 8cabdff1aSopenharmony_ci * Copyright 2007 Collabora Ltd, Philippe Kalaf 9cabdff1aSopenharmony_ci * Copyright 2010 Mark Nauwelaerts 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * This file is part of FFmpeg. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 14cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 16cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 19cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 20cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21cabdff1aSopenharmony_ci * Lesser General Public License for more details. 22cabdff1aSopenharmony_ci * 23cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 24cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 25cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#include "avformat.h" 29cabdff1aSopenharmony_ci#include "avio_internal.h" 30cabdff1aSopenharmony_ci#include "rtpdec_formats.h" 31cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 32cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 33cabdff1aSopenharmony_ci#include "libavcodec/get_bits.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_cistruct PayloadContext { 36cabdff1aSopenharmony_ci AVIOContext *buf; 37cabdff1aSopenharmony_ci uint8_t endbyte; 38cabdff1aSopenharmony_ci int endbyte_bits; 39cabdff1aSopenharmony_ci uint32_t timestamp; 40cabdff1aSopenharmony_ci int newformat; 41cabdff1aSopenharmony_ci}; 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_cistatic void h263_close_context(PayloadContext *data) 44cabdff1aSopenharmony_ci{ 45cabdff1aSopenharmony_ci ffio_free_dyn_buf(&data->buf); 46cabdff1aSopenharmony_ci} 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_cistatic int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, 49cabdff1aSopenharmony_ci AVStream *st, AVPacket *pkt, uint32_t *timestamp, 50cabdff1aSopenharmony_ci const uint8_t *buf, int len, uint16_t seq, 51cabdff1aSopenharmony_ci int flags) 52cabdff1aSopenharmony_ci{ 53cabdff1aSopenharmony_ci /* Corresponding to header fields in the RFC */ 54cabdff1aSopenharmony_ci int f, p, i, sbit, ebit, src, r; 55cabdff1aSopenharmony_ci int header_size, ret; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci if (data->newformat) 58cabdff1aSopenharmony_ci return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len, 59cabdff1aSopenharmony_ci seq, flags); 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci if (data->buf && data->timestamp != *timestamp) { 62cabdff1aSopenharmony_ci /* Dropping old buffered, unfinished data */ 63cabdff1aSopenharmony_ci ffio_free_dyn_buf(&data->buf); 64cabdff1aSopenharmony_ci data->endbyte_bits = 0; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci if (len < 4) { 68cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet: %d\n", len); 69cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 70cabdff1aSopenharmony_ci } 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci f = buf[0] & 0x80; 73cabdff1aSopenharmony_ci p = buf[0] & 0x40; 74cabdff1aSopenharmony_ci if (!f) { 75cabdff1aSopenharmony_ci /* Mode A */ 76cabdff1aSopenharmony_ci header_size = 4; 77cabdff1aSopenharmony_ci i = buf[1] & 0x10; 78cabdff1aSopenharmony_ci r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5); 79cabdff1aSopenharmony_ci } else if (!p) { 80cabdff1aSopenharmony_ci /* Mode B */ 81cabdff1aSopenharmony_ci header_size = 8; 82cabdff1aSopenharmony_ci if (len < header_size) { 83cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, 84cabdff1aSopenharmony_ci "Too short H.263 RTP packet: %d bytes, %d header bytes\n", 85cabdff1aSopenharmony_ci len, header_size); 86cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 87cabdff1aSopenharmony_ci } 88cabdff1aSopenharmony_ci r = buf[3] & 0x03; 89cabdff1aSopenharmony_ci i = buf[4] & 0x80; 90cabdff1aSopenharmony_ci } else { 91cabdff1aSopenharmony_ci /* Mode C */ 92cabdff1aSopenharmony_ci header_size = 12; 93cabdff1aSopenharmony_ci if (len < header_size) { 94cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, 95cabdff1aSopenharmony_ci "Too short H.263 RTP packet: %d bytes, %d header bytes\n", 96cabdff1aSopenharmony_ci len, header_size); 97cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 98cabdff1aSopenharmony_ci } 99cabdff1aSopenharmony_ci r = buf[3] & 0x03; 100cabdff1aSopenharmony_ci i = buf[4] & 0x80; 101cabdff1aSopenharmony_ci } 102cabdff1aSopenharmony_ci sbit = (buf[0] >> 3) & 0x7; 103cabdff1aSopenharmony_ci ebit = buf[0] & 0x7; 104cabdff1aSopenharmony_ci src = (buf[1] & 0xe0) >> 5; 105cabdff1aSopenharmony_ci if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */ 106cabdff1aSopenharmony_ci if ((src == 0 || src >= 6) && r) { 107cabdff1aSopenharmony_ci /* Invalid src for this format, and bits that should be zero 108cabdff1aSopenharmony_ci * according to RFC 2190 aren't zero. */ 109cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_WARNING, 110cabdff1aSopenharmony_ci "Interpreting H.263 RTP data as RFC 2429/4629 even though " 111cabdff1aSopenharmony_ci "signalled with a static payload type.\n"); 112cabdff1aSopenharmony_ci data->newformat = 1; 113cabdff1aSopenharmony_ci return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, 114cabdff1aSopenharmony_ci len, seq, flags); 115cabdff1aSopenharmony_ci } 116cabdff1aSopenharmony_ci } 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci buf += header_size; 119cabdff1aSopenharmony_ci len -= header_size; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci if (!data->buf) { 122cabdff1aSopenharmony_ci /* Check the picture start code, only start buffering a new frame 123cabdff1aSopenharmony_ci * if this is correct */ 124cabdff1aSopenharmony_ci if (len > 4 && AV_RB32(buf) >> 10 == 0x20) { 125cabdff1aSopenharmony_ci ret = avio_open_dyn_buf(&data->buf); 126cabdff1aSopenharmony_ci if (ret < 0) 127cabdff1aSopenharmony_ci return ret; 128cabdff1aSopenharmony_ci data->timestamp = *timestamp; 129cabdff1aSopenharmony_ci } else { 130cabdff1aSopenharmony_ci /* Frame not started yet, skipping */ 131cabdff1aSopenharmony_ci return AVERROR(EAGAIN); 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci if (data->endbyte_bits || sbit) { 136cabdff1aSopenharmony_ci if (data->endbyte_bits == sbit) { 137cabdff1aSopenharmony_ci data->endbyte |= buf[0] & (0xff >> sbit); 138cabdff1aSopenharmony_ci data->endbyte_bits = 0; 139cabdff1aSopenharmony_ci buf++; 140cabdff1aSopenharmony_ci len--; 141cabdff1aSopenharmony_ci avio_w8(data->buf, data->endbyte); 142cabdff1aSopenharmony_ci } else { 143cabdff1aSopenharmony_ci /* Start/end skip bits not matching - missed packets? */ 144cabdff1aSopenharmony_ci GetBitContext gb; 145cabdff1aSopenharmony_ci ret = init_get_bits(&gb, buf, len*8 - ebit); 146cabdff1aSopenharmony_ci if (ret < 0) 147cabdff1aSopenharmony_ci return ret; 148cabdff1aSopenharmony_ci skip_bits(&gb, sbit); 149cabdff1aSopenharmony_ci if (data->endbyte_bits) { 150cabdff1aSopenharmony_ci data->endbyte |= get_bits(&gb, 8 - data->endbyte_bits); 151cabdff1aSopenharmony_ci avio_w8(data->buf, data->endbyte); 152cabdff1aSopenharmony_ci } 153cabdff1aSopenharmony_ci while (get_bits_left(&gb) >= 8) 154cabdff1aSopenharmony_ci avio_w8(data->buf, get_bits(&gb, 8)); 155cabdff1aSopenharmony_ci data->endbyte_bits = get_bits_left(&gb); 156cabdff1aSopenharmony_ci if (data->endbyte_bits) 157cabdff1aSopenharmony_ci data->endbyte = get_bits(&gb, data->endbyte_bits) << 158cabdff1aSopenharmony_ci (8 - data->endbyte_bits); 159cabdff1aSopenharmony_ci ebit = 0; 160cabdff1aSopenharmony_ci len = 0; 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci } 163cabdff1aSopenharmony_ci if (ebit) { 164cabdff1aSopenharmony_ci if (len > 0) 165cabdff1aSopenharmony_ci avio_write(data->buf, buf, len - 1); 166cabdff1aSopenharmony_ci data->endbyte_bits = 8 - ebit; 167cabdff1aSopenharmony_ci data->endbyte = buf[len - 1] & (0xff << ebit); 168cabdff1aSopenharmony_ci } else { 169cabdff1aSopenharmony_ci avio_write(data->buf, buf, len); 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci 172cabdff1aSopenharmony_ci if (!(flags & RTP_FLAG_MARKER)) 173cabdff1aSopenharmony_ci return AVERROR(EAGAIN); 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci if (data->endbyte_bits) 176cabdff1aSopenharmony_ci avio_w8(data->buf, data->endbyte); 177cabdff1aSopenharmony_ci data->endbyte_bits = 0; 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ci ret = ff_rtp_finalize_packet(pkt, &data->buf, st->index); 180cabdff1aSopenharmony_ci if (ret < 0) 181cabdff1aSopenharmony_ci return ret; 182cabdff1aSopenharmony_ci if (!i) 183cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ci return 0; 186cabdff1aSopenharmony_ci} 187cabdff1aSopenharmony_ci 188cabdff1aSopenharmony_ciconst RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = { 189cabdff1aSopenharmony_ci .codec_type = AVMEDIA_TYPE_VIDEO, 190cabdff1aSopenharmony_ci .codec_id = AV_CODEC_ID_H263, 191cabdff1aSopenharmony_ci .need_parsing = AVSTREAM_PARSE_FULL, 192cabdff1aSopenharmony_ci .parse_packet = h263_handle_packet, 193cabdff1aSopenharmony_ci .priv_data_size = sizeof(PayloadContext), 194cabdff1aSopenharmony_ci .close = h263_close_context, 195cabdff1aSopenharmony_ci .static_payload_id = 34, 196cabdff1aSopenharmony_ci}; 197