00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "avformat.h"
00029 #include "rtpdec_formats.h"
00030 #include "libavutil/intreadwrite.h"
00031 #include "libavcodec/get_bits.h"
00032
00033 struct PayloadContext {
00034 AVIOContext *buf;
00035 uint8_t endbyte;
00036 int endbyte_bits;
00037 uint32_t timestamp;
00038 int newformat;
00039 };
00040
00041 static PayloadContext *h263_new_context(void)
00042 {
00043 return av_mallocz(sizeof(PayloadContext));
00044 }
00045
00046 static void h263_free_context(PayloadContext *data)
00047 {
00048 if (!data)
00049 return;
00050 if (data->buf) {
00051 uint8_t *p;
00052 avio_close_dyn_buf(data->buf, &p);
00053 av_free(p);
00054 }
00055 av_free(data);
00056 }
00057
00058 static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
00059 AVStream *st, AVPacket *pkt, uint32_t *timestamp,
00060 const uint8_t *buf, int len, int flags)
00061 {
00062
00063 int f, p, i, sbit, ebit, src, r;
00064 int header_size;
00065
00066 if (data->newformat)
00067 return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
00068 flags);
00069
00070 if (data->buf && data->timestamp != *timestamp) {
00071
00072 uint8_t *p;
00073 avio_close_dyn_buf(data->buf, &p);
00074 av_free(p);
00075 data->buf = NULL;
00076 }
00077
00078 if (len < 4) {
00079 av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet: %d\n", len);
00080 return AVERROR_INVALIDDATA;
00081 }
00082
00083 f = buf[0] & 0x80;
00084 p = buf[0] & 0x40;
00085 if (!f) {
00086
00087 header_size = 4;
00088 i = buf[1] & 0x10;
00089 r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
00090 } else if (!p) {
00091
00092 header_size = 8;
00093 if (len < header_size) {
00094 av_log(ctx, AV_LOG_ERROR,
00095 "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
00096 len, header_size);
00097 return AVERROR_INVALIDDATA;
00098 }
00099 r = buf[3] & 0x03;
00100 i = buf[4] & 0x80;
00101 } else {
00102
00103 header_size = 12;
00104 if (len < header_size) {
00105 av_log(ctx, AV_LOG_ERROR,
00106 "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
00107 len, header_size);
00108 return AVERROR_INVALIDDATA;
00109 }
00110 r = buf[3] & 0x03;
00111 i = buf[4] & 0x80;
00112 }
00113 sbit = (buf[0] >> 3) & 0x7;
00114 ebit = buf[0] & 0x7;
00115 src = (buf[1] & 0xe0) >> 5;
00116 if (!(buf[0] & 0xf8)) {
00117 if ((src == 0 || src >= 6) && r) {
00118
00119
00120 av_log(ctx, AV_LOG_WARNING,
00121 "Interpreting H263 RTP data as RFC 2429/4629 even though "
00122 "signalled with a static payload type.\n");
00123 data->newformat = 1;
00124 return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
00125 len, flags);
00126 }
00127 }
00128
00129 buf += header_size;
00130 len -= header_size;
00131
00132 if (!data->buf) {
00133
00134
00135 if (!f && len > 4 && AV_RB32(buf) >> 10 == 0x20) {
00136 int ret = avio_open_dyn_buf(&data->buf);
00137 if (ret < 0)
00138 return ret;
00139 data->timestamp = *timestamp;
00140 } else {
00141
00142 return AVERROR(EAGAIN);
00143 }
00144 }
00145
00146 if (data->endbyte_bits || sbit) {
00147 if (data->endbyte_bits == sbit) {
00148 data->endbyte |= buf[0] & (0xff >> sbit);
00149 data->endbyte_bits = 0;
00150 buf++;
00151 len--;
00152 avio_w8(data->buf, data->endbyte);
00153 } else {
00154
00155 GetBitContext gb;
00156 init_get_bits(&gb, buf, len*8 - ebit);
00157 skip_bits(&gb, sbit);
00158 if (data->endbyte_bits) {
00159 data->endbyte |= get_bits(&gb, 8 - data->endbyte_bits);
00160 avio_w8(data->buf, data->endbyte);
00161 }
00162 while (get_bits_left(&gb) >= 8)
00163 avio_w8(data->buf, get_bits(&gb, 8));
00164 data->endbyte_bits = get_bits_left(&gb);
00165 if (data->endbyte_bits)
00166 data->endbyte = get_bits(&gb, data->endbyte_bits) <<
00167 (8 - data->endbyte_bits);
00168 ebit = 0;
00169 len = 0;
00170 }
00171 }
00172 if (ebit) {
00173 if (len > 0)
00174 avio_write(data->buf, buf, len - 1);
00175 data->endbyte_bits = 8 - ebit;
00176 data->endbyte = buf[len - 1] & (0xff << ebit);
00177 } else {
00178 avio_write(data->buf, buf, len);
00179 }
00180
00181 if (!(flags & RTP_FLAG_MARKER))
00182 return AVERROR(EAGAIN);
00183
00184 if (data->endbyte_bits)
00185 avio_w8(data->buf, data->endbyte);
00186 data->endbyte_bits = 0;
00187
00188 av_init_packet(pkt);
00189 pkt->size = avio_close_dyn_buf(data->buf, &pkt->data);
00190 pkt->destruct = av_destruct_packet;
00191 pkt->stream_index = st->index;
00192 if (!i)
00193 pkt->flags |= AV_PKT_FLAG_KEY;
00194 data->buf = NULL;
00195
00196 return 0;
00197 }
00198
00199 RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = {
00200 .codec_type = AVMEDIA_TYPE_VIDEO,
00201 .codec_id = CODEC_ID_H263,
00202 .parse_packet = h263_handle_packet,
00203 .alloc = h263_new_context,
00204 .free = h263_free_context,
00205 .static_payload_id = 34,
00206 };