[FFmpeg-devel] [PATCH] RTMP client support for lavf
Kostya
kostya.shishkov
Thu Jul 30 08:16:22 CEST 2009
On Thu, Jul 30, 2009 at 03:10:23AM +0200, Michael Niedermayer wrote:
> On Wed, Jul 29, 2009 at 09:26:05AM +0300, Kostya wrote:
>
> [...]
>
> > +int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
> > + int chunk_size, RTMPPacket *prev_pkt)
> > +{
> > + uint8_t hdr, t, buf[16];
> > + int channel_id, timestamp, data_size, offset = 0;
> > + uint32_t extra = 0;
> > + uint8_t type;
> > +
> > + if (url_read(h, &hdr, 1) != 1) {
> > + return AVERROR(EIO);
> > + }
> > + channel_id = hdr & 0x3F;
> > +
> > + hdr >>= 6;
> > + if (hdr == RTMP_PS_ONEBYTE) {
> > + //todo
> > + return -1;
> > + } else {
> > + if (url_read_complete(h, buf, 3) != 3)
> > + return AVERROR(EIO);
> > + timestamp = AV_RB24(buf);
> > + if (hdr != RTMP_PS_FOURBYTES) {
> > + if (url_read_complete(h, buf, 3) != 3)
> > + return AVERROR(EIO);
> > + data_size = AV_RB24(buf);
> > + if (url_read_complete(h, &type, 1) != 1)
> > + return AVERROR(EIO);
> > + if (hdr == RTMP_PS_TWELVEBYTES) {
> > + if (url_read_complete(h, buf, 4) != 4)
> > + return AVERROR(EIO);
> > + extra = AV_RL32(buf);
> > + } else {
> > + extra = prev_pkt[channel_id].extra;
> > + }
> > + } else {
> > + data_size = prev_pkt[channel_id].data_size;
> > + type = prev_pkt[channel_id].type;
> > + extra = prev_pkt[channel_id].extra;
> > + }
>
> data_size = prev_pkt[channel_id].data_size;
> type = prev_pkt[channel_id].type;
> extra = prev_pkt[channel_id].extra;
>
> if()
> data_size = AV_RB24(buf);
> ...
changed
> > + }
> > + if (ff_rtmp_packet_create(p, channel_id, type, timestamp, data_size))
> > + return -1;
> > + p->extra = extra;
> > + // save history
> > + prev_pkt[channel_id].channel_id = channel_id;
> > + prev_pkt[channel_id].type = type;
> > + prev_pkt[channel_id].data_size = data_size;
> > + prev_pkt[channel_id].timestamp = timestamp;
> > + prev_pkt[channel_id].extra = extra;
> > + while (data_size > 0) {
> > + int toread = FFMIN(data_size, chunk_size);
> > + if (url_read_complete(h, p->data + offset, toread) != toread) {
> > + ff_rtmp_packet_destroy(p);
> > + return AVERROR(EIO);
> > + }
> > + data_size -= chunk_size;
> > + offset += chunk_size;
> > + if (data_size > 0) {
> > + url_read_complete(h, &t, 1); //marker
> > + if (t != (0xC0 + channel_id))
> > + return -1;
> > + }
> > + }
> > + return 0;
> > +}
> > +
>
> [...]
>
> > +int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end,
> > + const uint8_t *name, uint8_t *dst, int dst_size)
> > +{
> > + int namelen = strlen(name);
> > + int len;
> > +
> > + if (data >= data_end - 3)
>
> i assume you meant
>
> 3 >= data_end - data
> ?
>
> because as written if data_end is NULL+2, this wouldnt work
yes
> > + return -1;
> > + if (*data++ != AMF_DATA_TYPE_OBJECT)
> > + return -1;
> > + for (;;) {
> > + int size = bytestream_get_be16(&data);
> > + if (!size)
> > + break;
>
> > + data += size;
>
> this can overflow
added overflow checks here and in other places
> > + if (data >= data_end)
> > + return -1;
> > + if (size == namelen && !memcmp(data-size, name, namelen)) {
> > + switch (*data++) {
> > + case AMF_DATA_TYPE_NUMBER:
> > + snprintf(dst, dst_size, "%g", av_int2dbl(AV_RB64(data)));
> > + return 0;
> > + case AMF_DATA_TYPE_BOOL:
> > + snprintf(dst, dst_size, "%s", *data ? "true" : "false");
> > + return 0;
> > + case AMF_DATA_TYPE_STRING:
> > + len = bytestream_get_be16(&data);
> > + av_strlcpy(dst, data, FFMIN(len+1, dst_size));
> > + return 0;
> > + default:
> > + return -1;
> > + }
>
> the return 0 can be factored out
factored out
> > + }
> > + len = ff_amf_tag_size(data, data_end);
> > + if (len < 0 || data + len >= data_end)
> > + return -1;
>
> again overflow
> and there are more ...
>
> > + data += len;
> > + }
> > + return -1;
> > +}
> [...]
>
> > +/**
> > + * structure for holding RTMP packets
> > + */
> > +typedef struct RTMPPacket {
> > + uint8_t channel_id; ///< RTMP channel ID (nothing to do with audio/video channels though)
> > + RTMPPacketType type; ///< packet payload type
> > + uint32_t timestamp; ///< packet timestamp increment to the previous one (in milliseconds)
>
> id call it timestamp_delta or _diff if its not a absolute timestamp
err, the funny thing it serves as both depending on packet type
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rtmp.patch
Type: text/x-diff
Size: 43105 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090730/a9210c2e/attachment.patch>
More information about the ffmpeg-devel
mailing list