00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avformat.h"
00023 #include "rtpdec_formats.h"
00024 #include "libavutil/intreadwrite.h"
00025
00026 static int h263_handle_packet(AVFormatContext *ctx,
00027 PayloadContext *data,
00028 AVStream *st,
00029 AVPacket * pkt,
00030 uint32_t * timestamp,
00031 const uint8_t * buf,
00032 int len, int flags)
00033 {
00034 uint8_t *ptr;
00035 uint16_t header;
00036 int startcode, vrc, picture_header;
00037
00038 if (len < 2) {
00039 av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet\n");
00040 return AVERROR_INVALIDDATA;
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 header = AV_RB16(buf);
00057 startcode = (header & 0x0400) >> 9;
00058 vrc = header & 0x0200;
00059 picture_header = (header & 0x01f8) >> 3;
00060 buf += 2;
00061 len -= 2;
00062
00063 if (vrc) {
00064
00065 buf += 1;
00066 len -= 1;
00067 }
00068 if (picture_header) {
00069
00070 buf += picture_header;
00071 len -= picture_header;
00072 }
00073
00074 if (len < 0) {
00075 av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet\n");
00076 return AVERROR_INVALIDDATA;
00077 }
00078
00079 if (av_new_packet(pkt, len + startcode)) {
00080 av_log(ctx, AV_LOG_ERROR, "Out of memory\n");
00081 return AVERROR(ENOMEM);
00082 }
00083 pkt->stream_index = st->index;
00084 ptr = pkt->data;
00085
00086 if (startcode) {
00087 *ptr++ = 0;
00088 *ptr++ = 0;
00089 }
00090 memcpy(ptr, buf, len);
00091
00092 return 0;
00093 }
00094
00095 RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = {
00096 .enc_name = "H263-1998",
00097 .codec_type = AVMEDIA_TYPE_VIDEO,
00098 .codec_id = CODEC_ID_H263,
00099 .parse_packet = h263_handle_packet,
00100 };
00101
00102 RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = {
00103 .enc_name = "H263-2000",
00104 .codec_type = AVMEDIA_TYPE_VIDEO,
00105 .codec_id = CODEC_ID_H263,
00106 .parse_packet = h263_handle_packet,
00107 };
00108