00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00029 #include <string.h>
00030 #include "libavutil/intreadwrite.h"
00031 #include "rtp.h"
00032 #include "rtpdec.h"
00033 #include "rtpdec_formats.h"
00034
00035 struct PayloadContext {
00036 AVIOContext *pktbuf;
00037 int64_t timestamp;
00038 };
00039
00041 static int svq3_parse_packet (AVFormatContext *s, PayloadContext *sv,
00042 AVStream *st, AVPacket *pkt,
00043 uint32_t *timestamp,
00044 const uint8_t *buf, int len, int flags)
00045 {
00046 int config_packet, start_packet, end_packet;
00047
00048 if (len < 2)
00049 return AVERROR_INVALIDDATA;
00050
00051 config_packet = buf[0] & 0x40;
00052 start_packet = buf[0] & 0x20;
00053 end_packet = buf[0] & 0x10;
00054 buf += 2;
00055 len -= 2;
00056
00057 if (config_packet) {
00058
00059 av_freep(&st->codec->extradata);
00060 st->codec->extradata_size = 0;
00061
00062 if (len < 2 || !(st->codec->extradata =
00063 av_malloc(len + 8 + FF_INPUT_BUFFER_PADDING_SIZE)))
00064 return AVERROR_INVALIDDATA;
00065
00066 st->codec->extradata_size = len + 8;
00067 memcpy(st->codec->extradata, "SEQH", 4);
00068 AV_WB32(st->codec->extradata + 4, len);
00069 memcpy(st->codec->extradata + 8, buf, len);
00070
00071
00072
00073
00074
00075
00076 st->codec->codec_id = AV_CODEC_ID_SVQ3;
00077
00078 return AVERROR(EAGAIN);
00079 }
00080
00081 if (start_packet) {
00082 int res;
00083
00084 if (sv->pktbuf) {
00085 uint8_t *tmp;
00086 avio_close_dyn_buf(sv->pktbuf, &tmp);
00087 av_free(tmp);
00088 }
00089 if ((res = avio_open_dyn_buf(&sv->pktbuf)) < 0)
00090 return res;
00091 sv->timestamp = *timestamp;
00092 }
00093
00094 if (!sv->pktbuf)
00095 return AVERROR_INVALIDDATA;
00096
00097 avio_write(sv->pktbuf, buf, len);
00098
00099 if (end_packet) {
00100 av_init_packet(pkt);
00101 pkt->stream_index = st->index;
00102 *timestamp = sv->timestamp;
00103 pkt->size = avio_close_dyn_buf(sv->pktbuf, &pkt->data);
00104 pkt->destruct = av_destruct_packet;
00105 sv->pktbuf = NULL;
00106 return 0;
00107 }
00108
00109 return AVERROR(EAGAIN);
00110 }
00111
00112 static PayloadContext *svq3_extradata_new(void)
00113 {
00114 return av_mallocz(sizeof(PayloadContext));
00115 }
00116
00117 static void svq3_extradata_free(PayloadContext *sv)
00118 {
00119 if (sv->pktbuf) {
00120 uint8_t *buf;
00121 avio_close_dyn_buf(sv->pktbuf, &buf);
00122 av_free(buf);
00123 }
00124 av_free(sv);
00125 }
00126
00127 RTPDynamicProtocolHandler ff_svq3_dynamic_handler = {
00128 .enc_name = "X-SV3V-ES",
00129 .codec_type = AVMEDIA_TYPE_VIDEO,
00130 .codec_id = AV_CODEC_ID_NONE,
00131 .alloc = svq3_extradata_new,
00132 .free = svq3_extradata_free,
00133 .parse_packet = svq3_parse_packet,
00134 };