| Index: source/patched-ffmpeg-mt/libavformat/rtpdec.c | 
| =================================================================== | 
| --- source/patched-ffmpeg-mt/libavformat/rtpdec.c	(revision 65184) | 
| +++ source/patched-ffmpeg-mt/libavformat/rtpdec.c	(working copy) | 
| @@ -471,18 +471,17 @@ | 
| if (!st) { | 
| /* specific MPEG2TS demux support */ | 
| ret = ff_mpegts_parse_packet(s->ts, pkt, buf, len); | 
| -        if (ret < 0) { | 
| -            s->prev_ret = -1; | 
| -            return -1; | 
| -        } | 
| +        /* The only error that can be returned from ff_mpegts_parse_packet | 
| +         * is "no more data to return from the provided buffer", so return | 
| +         * AVERROR(EAGAIN) for all errors */ | 
| +        if (ret < 0) | 
| +            return AVERROR(EAGAIN); | 
| if (ret < len) { | 
| s->read_buf_size = len - ret; | 
| memcpy(s->buf, buf + ret, s->read_buf_size); | 
| s->read_buf_index = 0; | 
| -            s->prev_ret = 1; | 
| return 1; | 
| } | 
| -        s->prev_ret = 0; | 
| return 0; | 
| } else if (s->parse_packet) { | 
| rv = s->parse_packet(s->ic, s->dynamic_protocol_context, | 
| @@ -531,7 +530,6 @@ | 
| // now perform timestamp things.... | 
| finalize_packet(s, pkt, timestamp); | 
|  | 
| -    s->prev_ret = rv; | 
| return rv; | 
| } | 
|  | 
| @@ -579,7 +577,7 @@ | 
|  | 
| static int has_next_packet(RTPDemuxContext *s) | 
| { | 
| -    return s->queue && s->queue->seq == s->seq + 1; | 
| +    return s->queue && s->queue->seq == (uint16_t) (s->seq + 1); | 
| } | 
|  | 
| int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s) | 
| @@ -606,19 +604,10 @@ | 
| av_free(s->queue); | 
| s->queue = next; | 
| s->queue_len--; | 
| -    return rv ? rv : has_next_packet(s); | 
| +    return rv; | 
| } | 
|  | 
| -/** | 
| - * Parse an RTP or RTCP packet directly sent as a buffer. | 
| - * @param s RTP parse context. | 
| - * @param pkt returned packet | 
| - * @param bufptr pointer to the input buffer or NULL to read the next packets | 
| - * @param len buffer len | 
| - * @return 0 if a packet is returned, 1 if a packet is returned and more can follow | 
| - * (use buf as NULL to read the next). -1 if no packet (error or no more packet). | 
| - */ | 
| -int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, | 
| +static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt, | 
| uint8_t **bufptr, int len) | 
| { | 
| uint8_t* buf = bufptr ? *bufptr : NULL; | 
| @@ -627,10 +616,10 @@ | 
| int rv= 0; | 
|  | 
| if (!buf) { | 
| -        /* If parsing of the previous packet actually returned 0, there's | 
| -         * nothing more to be parsed from that packet, but we may have | 
| +        /* If parsing of the previous packet actually returned 0 or an error, | 
| +         * there's nothing more to be parsed from that packet, but we may have | 
| * indicated that we can return the next enqueued packet. */ | 
| -        if (!s->prev_ret) | 
| +        if (s->prev_ret <= 0) | 
| return rtp_parse_queued_packet(s, pkt); | 
| /* return the next packets, if any */ | 
| if(s->st && s->parse_packet) { | 
| @@ -640,27 +629,20 @@ | 
| rv= s->parse_packet(s->ic, s->dynamic_protocol_context, | 
| s->st, pkt, ×tamp, NULL, 0, flags); | 
| finalize_packet(s, pkt, timestamp); | 
| -            s->prev_ret = rv; | 
| -            return rv ? rv : has_next_packet(s); | 
| +            return rv; | 
| } else { | 
| // TODO: Move to a dynamic packet handler (like above) | 
| -            if (s->read_buf_index >= s->read_buf_size) { | 
| -                s->prev_ret = -1; | 
| -                return -1; | 
| -            } | 
| +            if (s->read_buf_index >= s->read_buf_size) | 
| +                return AVERROR(EAGAIN); | 
| ret = ff_mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index, | 
| s->read_buf_size - s->read_buf_index); | 
| -            if (ret < 0) { | 
| -                s->prev_ret = -1; | 
| -                return -1; | 
| -            } | 
| +            if (ret < 0) | 
| +                return AVERROR(EAGAIN); | 
| s->read_buf_index += ret; | 
| if (s->read_buf_index < s->read_buf_size) | 
| return 1; | 
| -            else { | 
| -                s->prev_ret = 0; | 
| -                return has_next_packet(s); | 
| -            } | 
| +            else | 
| +                return 0; | 
| } | 
| } | 
|  | 
| @@ -673,7 +655,7 @@ | 
| return rtcp_parse_packet(s, buf, len); | 
| } | 
|  | 
| -    if (s->seq == 0 || s->queue_size <= 1) { | 
| +    if ((s->seq == 0 && !s->queue) || s->queue_size <= 1) { | 
| /* First packet, or no reordering */ | 
| return rtp_parse_packet_internal(s, pkt, buf, len); | 
| } else { | 
| @@ -687,7 +669,7 @@ | 
| } else if (diff <= 1) { | 
| /* Correct packet */ | 
| rv = rtp_parse_packet_internal(s, pkt, buf, len); | 
| -            return rv ? rv : has_next_packet(s); | 
| +            return rv; | 
| } else { | 
| /* Still missing some packet, enqueue this one. */ | 
| enqueue_packet(s, buf, len); | 
| @@ -701,6 +683,25 @@ | 
| } | 
| } | 
|  | 
| +/** | 
| + * Parse an RTP or RTCP packet directly sent as a buffer. | 
| + * @param s RTP parse context. | 
| + * @param pkt returned packet | 
| + * @param bufptr pointer to the input buffer or NULL to read the next packets | 
| + * @param len buffer len | 
| + * @return 0 if a packet is returned, 1 if a packet is returned and more can follow | 
| + * (use buf as NULL to read the next). -1 if no packet (error or no more packet). | 
| + */ | 
| +int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, | 
| +                     uint8_t **bufptr, int len) | 
| +{ | 
| +    int rv = rtp_parse_one_packet(s, pkt, bufptr, len); | 
| +    s->prev_ret = rv; | 
| +    while (rv == AVERROR(EAGAIN) && has_next_packet(s)) | 
| +        rv = rtp_parse_queued_packet(s, pkt); | 
| +    return rv ? rv : has_next_packet(s); | 
| +} | 
| + | 
| void rtp_parse_close(RTPDemuxContext *s) | 
| { | 
| ff_rtp_reset_packet_queue(s); | 
|  |