[FFmpeg-devel] [PATCH] RTMP client support for lavf
Kostya
kostya.shishkov
Tue Jul 28 08:27:11 CEST 2009
On Fri, Jul 24, 2009 at 03:08:32AM +0200, Michael Niedermayer wrote:
> On Thu, Jul 23, 2009 at 06:34:13AM +0300, Kostya wrote:
> > On Wed, Jul 22, 2009 at 12:01:46PM +0200, Michael Niedermayer wrote:
> > > On Wed, Jul 22, 2009 at 07:58:05AM +0300, Kostya wrote:
> > > > On Tue, Jul 21, 2009 at 11:30:26PM +0200, Michael Niedermayer wrote:
> > > > > On Tue, Jul 21, 2009 at 11:04:09AM +0300, Kostya wrote:
> > > > > > On Mon, Jul 20, 2009 at 05:05:41PM +0200, Michael Niedermayer wrote:
> > > > > > > On Sat, Jul 18, 2009 at 08:01:17PM +0300, Kostya wrote:
> > > > > > > > On Sat, Jul 18, 2009 at 11:29:34AM +0200, Michael Niedermayer wrote:
> > > > > > > > > On Fri, Jul 17, 2009 at 06:38:46PM +0300, Kostya wrote:
[...]
> > + if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
> > + uint8_t tmpstr[256];
> > +
> > + if (!ff_amf_find_field(pkt->data + 9, pkt->data + pkt->data_size,
> > + "description", tmpstr, sizeof(tmpstr)))
> > + av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
> > + return -1;
> > + }
> > + if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
> > + switch (rt->state) {
> > + case STATE_HANDSHAKED:
> > + gen_create_stream(s, rt);
> > + rt->state = STATE_CONNECTING;
> > + break;
> > + case STATE_CONNECTING:
> > + //extract a number from result
> > + if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
> > + av_log(LOG_CONTEXT, AV_LOG_WARNING, "Unexpected reply on connect()\n");
> > + } else {
> > + rt->main_channel_id = (int) av_int2dbl(AV_RB64(pkt->data + 21));
> > + }
> > + gen_play(s, rt);
> > + rt->state = STATE_READY;
> > + break;
> > + }
> > + }
> > + if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
>
> else if
elsif'ed
> also shouldnt there be checks against receiving the wrong thing in the wrong
> state?
well, because I can't be sure about what is wrong and I'm as willing to
read Adobe spec as you're willing sign some agreement (for the same
reason too).
> [...]
> > +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;
> > + }
> > + }
> > + 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);
> > + int r;
> > + if ((r = url_read_complete(h, p->data + offset, toread)) != toread) {
>
> r seems unused
dropped
> [...]
> > +/**
> > + * Creates new RTMP packet with given attributes.
> > + *
> > + * @param pkt packet
> > + * @param channel_id packet channel ID
> > + * @param type packet type
> > + * @param timestamp packet timestamp
> > + * @param size packet size
> > + * @return zero on success, negative value otherwise
> > + */
> > +int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
> > + int timestamp, int size);
> > +
> > +/**
> > + * Frees RTMP packet.
> > + *
> > + * @param pkt packet
> > + */
> > +void ff_rtmp_packet_destroy(RTMPPacket *pkt);
> > +
>
> > +/**
> > + * Reads RTMP packet.
>
> reads from where?
explained
> > + *
> > + * @param h reader context
> > + * @param p packet
> > + * @param chunk_size current chunk size
> > + * @param prev_pkt previously read packet headers for all channels
> > + * (may be needed for restoring incomplete packet header)
> > + * @return zero on success, negative value otherwise
> > + */
> > +int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
> > + int chunk_size, RTMPPacket *prev_pkt);
> > +
> > +/**
> > + * Sends RTMP packet.
>
> sends to where?
> i think you could be a little bit more verbose ...
I seem to lack -v option.
> > + *
> > + * @param h reader context
> > + * @param p packet to send
> > + * @param chunk_size current chunk size
> > + * @param prev_pkt previously sent packet headers for all channels
> > + * (may be used for packet header compressing)
> > + * @return zero on success, negative value otherwise
> > + */
> > +int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p,
> > + int chunk_size, RTMPPacket *prev_pkt);
> > +
> > +/**
> > + * @defgroup amffuncs functions used to work with AMF format (which is also used in .flv)
> > + * @see amf_* funcs in libavformat/flvdec.c
> > + * @{
> > + */
> > +
>
> > +/**
> > + * Calculates number of bytes needed to skip first AMF entry in data.
> > + *
> > + * @param data input data
> > + * @param data_end input buffer end
> > + * @return number of bytes used by first AMF entry
> > + */
> > +int ff_amf_skip_data(const uint8_t *data, const uint8_t *data_end);
> > +
>
> the function name is misleading becauase it does not "skip data"
> rather it finds the size of the next element
renamed
> > +/**
> > + * Retrieves value of given AMF object field in string form.
> > + *
> > + * @param data AMF object data
> > + * @param data_end input buffer end
> > + * @param name name of field to retrieve
> > + * @param dst buffer for storing result
> > + * @param dst_size output buffer size
> > + * @return 0 if search and retrieval succeeded, negative value otherwise
> > + */
> > +int ff_amf_find_field(const uint8_t *data, const uint8_t *data_end,
> > + const uint8_t *name, uint8_t *dst, int dst_size);
>
> if i interpret the doxy correctly
> read_field_as_string seems a better name
renamed to ff_amf_get_field_value(). _as_string suffix is rather useless
since string is universal format.
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rtmp.patch
Type: text/x-diff
Size: 42900 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090728/bfe356c5/attachment.patch>
More information about the ffmpeg-devel
mailing list