1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * RTP H.263 Depacketizer, RFC 4629 3cabdff1aSopenharmony_ci * Copyright (c) 2010 Martin Storsjo 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "avformat.h" 23cabdff1aSopenharmony_ci#include "rtpdec_formats.h" 24cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 25cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ciint ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, 28cabdff1aSopenharmony_ci AVStream *st, AVPacket *pkt, uint32_t *timestamp, 29cabdff1aSopenharmony_ci const uint8_t *buf, int len, uint16_t seq, int flags) 30cabdff1aSopenharmony_ci{ 31cabdff1aSopenharmony_ci uint8_t *ptr; 32cabdff1aSopenharmony_ci uint16_t header; 33cabdff1aSopenharmony_ci int startcode, vrc, picture_header, ret; 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci if (len < 2) { 36cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet\n"); 37cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 38cabdff1aSopenharmony_ci } 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_ci /* Decode the 16 bit H.263+ payload header, as described in section 41cabdff1aSopenharmony_ci * 5.1 of RFC 4629. The fields of this header are: 42cabdff1aSopenharmony_ci * - 5 reserved bits, should be ignored. 43cabdff1aSopenharmony_ci * - One bit (P, startcode), indicating a picture start, picture segment 44cabdff1aSopenharmony_ci * start or video sequence end. If set, two zero bytes should be 45cabdff1aSopenharmony_ci * prepended to the payload. 46cabdff1aSopenharmony_ci * - One bit (V, vrc), indicating the presence of an 8 bit Video 47cabdff1aSopenharmony_ci * Redundancy Coding field after this 16 bit header. 48cabdff1aSopenharmony_ci * - 6 bits (PLEN, picture_header), the length (in bytes) of an extra 49cabdff1aSopenharmony_ci * picture header, following the VRC field. 50cabdff1aSopenharmony_ci * - 3 bits (PEBIT), the number of bits to ignore of the last byte 51cabdff1aSopenharmony_ci * of the extra picture header. (Not used at the moment.) 52cabdff1aSopenharmony_ci */ 53cabdff1aSopenharmony_ci header = AV_RB16(buf); 54cabdff1aSopenharmony_ci startcode = (header & 0x0400) >> 9; 55cabdff1aSopenharmony_ci vrc = header & 0x0200; 56cabdff1aSopenharmony_ci picture_header = (header & 0x01f8) >> 3; 57cabdff1aSopenharmony_ci buf += 2; 58cabdff1aSopenharmony_ci len -= 2; 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci if (vrc) { 61cabdff1aSopenharmony_ci /* Skip VRC header if present, not used at the moment. */ 62cabdff1aSopenharmony_ci buf += 1; 63cabdff1aSopenharmony_ci len -= 1; 64cabdff1aSopenharmony_ci } 65cabdff1aSopenharmony_ci if (picture_header) { 66cabdff1aSopenharmony_ci /* Skip extra picture header if present, not used at the moment. */ 67cabdff1aSopenharmony_ci buf += picture_header; 68cabdff1aSopenharmony_ci len -= picture_header; 69cabdff1aSopenharmony_ci } 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci if (len < 0) { 72cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet\n"); 73cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 74cabdff1aSopenharmony_ci } 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci if ((ret = av_new_packet(pkt, len + startcode)) < 0) { 77cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, "Out of memory\n"); 78cabdff1aSopenharmony_ci return ret; 79cabdff1aSopenharmony_ci } 80cabdff1aSopenharmony_ci pkt->stream_index = st->index; 81cabdff1aSopenharmony_ci ptr = pkt->data; 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci if (startcode) { 84cabdff1aSopenharmony_ci *ptr++ = 0; 85cabdff1aSopenharmony_ci *ptr++ = 0; 86cabdff1aSopenharmony_ci } 87cabdff1aSopenharmony_ci memcpy(ptr, buf, len); 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci return 0; 90cabdff1aSopenharmony_ci} 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ciconst RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = { 93cabdff1aSopenharmony_ci .enc_name = "H263-1998", 94cabdff1aSopenharmony_ci .codec_type = AVMEDIA_TYPE_VIDEO, 95cabdff1aSopenharmony_ci .codec_id = AV_CODEC_ID_H263, 96cabdff1aSopenharmony_ci .need_parsing = AVSTREAM_PARSE_FULL, 97cabdff1aSopenharmony_ci .parse_packet = ff_h263_handle_packet, 98cabdff1aSopenharmony_ci}; 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ciconst RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = { 101cabdff1aSopenharmony_ci .enc_name = "H263-2000", 102cabdff1aSopenharmony_ci .codec_type = AVMEDIA_TYPE_VIDEO, 103cabdff1aSopenharmony_ci .codec_id = AV_CODEC_ID_H263, 104cabdff1aSopenharmony_ci .need_parsing = AVSTREAM_PARSE_FULL, 105cabdff1aSopenharmony_ci .parse_packet = ff_h263_handle_packet, 106cabdff1aSopenharmony_ci}; 107