diff options
Diffstat (limited to 'ffmpeg/libavformat/rtpdec_vp8.c')
| -rw-r--r-- | ffmpeg/libavformat/rtpdec_vp8.c | 298 |
1 files changed, 0 insertions, 298 deletions
diff --git a/ffmpeg/libavformat/rtpdec_vp8.c b/ffmpeg/libavformat/rtpdec_vp8.c deleted file mode 100644 index b4b4f22..0000000 --- a/ffmpeg/libavformat/rtpdec_vp8.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * RTP VP8 Depacketizer - * Copyright (c) 2010 Josh Allmann - * Copyright (c) 2012 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief RTP support for the VP8 payload - * @author Josh Allmann <joshua.allmann@gmail.com> - * @see http://tools.ietf.org/html/draft-ietf-payload-vp8-05 - */ - -#include "libavcodec/bytestream.h" - -#include "rtpdec_formats.h" - -struct PayloadContext { - AVIOContext *data; - uint32_t timestamp; - int is_keyframe; - /* If sequence_ok is set, we keep returning data (even if we might have - * lost some data, but we haven't lost any too critical data that would - * cause the decoder to desynchronize and output random garbage). - */ - int sequence_ok; - int first_part_size; - uint16_t prev_seq; - int prev_pictureid; - int broken_frame; - /* If sequence_dirty is set, we have lost some data (critical or - * non-critical) and decoding will have some sort of artefacts, and - * we thus should request a new keyframe. - */ - int sequence_dirty; - int got_keyframe; -}; - -static void vp8_free_buffer(PayloadContext *vp8) -{ - uint8_t *tmp; - if (!vp8->data) - return; - avio_close_dyn_buf(vp8->data, &tmp); - av_free(tmp); - vp8->data = NULL; -} - -static int vp8_broken_sequence(AVFormatContext *ctx, PayloadContext *vp8, - const char *msg) -{ - vp8->sequence_ok = 0; - av_log(ctx, AV_LOG_WARNING, "%s", msg); - vp8_free_buffer(vp8); - return AVERROR(EAGAIN); -} - -static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8, - AVStream *st, AVPacket *pkt, uint32_t *timestamp, - const uint8_t *buf, int len, uint16_t seq, - int flags) -{ - int start_partition, end_packet; - int extended_bits, part_id; - int pictureid_present = 0, tl0picidx_present = 0, tid_present = 0, - keyidx_present = 0; - int pictureid = -1, pictureid_mask = 0; - int returned_old_frame = 0; - uint32_t old_timestamp = 0; - - if (!buf) { - if (vp8->data) { - int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index); - if (ret < 0) - return ret; - *timestamp = vp8->timestamp; - if (vp8->sequence_dirty) - pkt->flags |= AV_PKT_FLAG_CORRUPT; - return 0; - } - return AVERROR(EAGAIN); - } - - if (len < 1) - return AVERROR_INVALIDDATA; - - extended_bits = buf[0] & 0x80; - start_partition = buf[0] & 0x10; - part_id = buf[0] & 0x0f; - end_packet = flags & RTP_FLAG_MARKER; - buf++; - len--; - if (extended_bits) { - if (len < 1) - return AVERROR_INVALIDDATA; - pictureid_present = buf[0] & 0x80; - tl0picidx_present = buf[0] & 0x40; - tid_present = buf[0] & 0x20; - keyidx_present = buf[0] & 0x10; - buf++; - len--; - } - if (pictureid_present) { - if (len < 1) - return AVERROR_INVALIDDATA; - if (buf[0] & 0x80) { - if (len < 2) - return AVERROR_INVALIDDATA; - pictureid = AV_RB16(buf) & 0x7fff; - pictureid_mask = 0x7fff; - buf += 2; - len -= 2; - } else { - pictureid = buf[0] & 0x7f; - pictureid_mask = 0x7f; - buf++; - len--; - } - } - if (tl0picidx_present) { - // Ignoring temporal level zero index - buf++; - len--; - } - if (tid_present || keyidx_present) { - // Ignoring temporal layer index, layer sync bit and keyframe index - buf++; - len--; - } - if (len < 1) - return AVERROR_INVALIDDATA; - - if (start_partition && part_id == 0 && len >= 3) { - int res; - int non_key = buf[0] & 0x01; - if (!non_key) { - vp8_free_buffer(vp8); - // Keyframe, decoding ok again - vp8->sequence_ok = 1; - vp8->sequence_dirty = 0; - vp8->got_keyframe = 1; - } else { - int can_continue = vp8->data && !vp8->is_keyframe && - avio_tell(vp8->data) >= vp8->first_part_size; - if (!vp8->sequence_ok) - return AVERROR(EAGAIN); - if (!vp8->got_keyframe) - return vp8_broken_sequence(ctx, vp8, "Keyframe missing\n"); - if (pictureid >= 0) { - if (pictureid != ((vp8->prev_pictureid + 1) & pictureid_mask)) { - return vp8_broken_sequence(ctx, vp8, - "Missed a picture, sequence broken\n"); - } else { - if (vp8->data && !can_continue) - return vp8_broken_sequence(ctx, vp8, - "Missed a picture, sequence broken\n"); - } - } else { - uint16_t expected_seq = vp8->prev_seq + 1; - int16_t diff = seq - expected_seq; - if (vp8->data) { - // No picture id, so we can't know if missed packets - // contained any new frames. If diff == 0, we did get - // later packets from the same frame (matching timestamp), - // so we know we didn't miss any frame. If diff == 1 and - // we still have data (not flushed by the end of frame - // marker), the single missed packet must have been part - // of the same frame. - if ((diff == 0 || diff == 1) && can_continue) { - // Proceed with what we have - } else { - return vp8_broken_sequence(ctx, vp8, - "Missed too much, sequence broken\n"); - } - } else { - if (diff != 0) - return vp8_broken_sequence(ctx, vp8, - "Missed unknown data, sequence broken\n"); - } - } - if (vp8->data) { - vp8->sequence_dirty = 1; - if (avio_tell(vp8->data) >= vp8->first_part_size) { - int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index); - if (ret < 0) - return ret; - pkt->flags |= AV_PKT_FLAG_CORRUPT; - returned_old_frame = 1; - old_timestamp = vp8->timestamp; - } else { - // Shouldn't happen - vp8_free_buffer(vp8); - } - } - } - vp8->first_part_size = (AV_RL16(&buf[1]) << 3 | buf[0] >> 5) + 3; - if ((res = avio_open_dyn_buf(&vp8->data)) < 0) - return res; - vp8->timestamp = *timestamp; - vp8->broken_frame = 0; - vp8->prev_pictureid = pictureid; - vp8->is_keyframe = !non_key; - } else { - uint16_t expected_seq = vp8->prev_seq + 1; - - if (!vp8->sequence_ok) - return AVERROR(EAGAIN); - - if (vp8->timestamp != *timestamp) { - // Missed the start of the new frame, sequence broken - return vp8_broken_sequence(ctx, vp8, - "Received no start marker; dropping frame\n"); - } - - if (seq != expected_seq) { - if (vp8->is_keyframe) { - return vp8_broken_sequence(ctx, vp8, - "Missed part of a keyframe, sequence broken\n"); - } else if (vp8->data && avio_tell(vp8->data) >= vp8->first_part_size) { - vp8->broken_frame = 1; - vp8->sequence_dirty = 1; - } else { - return vp8_broken_sequence(ctx, vp8, - "Missed part of the first partition, sequence broken\n"); - } - } - } - - if (!vp8->data) - return vp8_broken_sequence(ctx, vp8, "Received no start marker\n"); - - vp8->prev_seq = seq; - if (!vp8->broken_frame) - avio_write(vp8->data, buf, len); - - if (returned_old_frame) { - *timestamp = old_timestamp; - return end_packet ? 1 : 0; - } - - if (end_packet) { - int ret; - ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index); - if (ret < 0) - return ret; - if (vp8->sequence_dirty) - pkt->flags |= AV_PKT_FLAG_CORRUPT; - return 0; - } - - return AVERROR(EAGAIN); -} - -static PayloadContext *vp8_new_context(void) -{ - PayloadContext *vp8 = av_mallocz(sizeof(PayloadContext)); - if (!vp8) - return NULL; - vp8->sequence_ok = 1; - return vp8; -} - -static void vp8_free_context(PayloadContext *vp8) -{ - vp8_free_buffer(vp8); - av_free(vp8); -} - -static int vp8_need_keyframe(PayloadContext *vp8) -{ - return vp8->sequence_dirty || !vp8->sequence_ok; -} - -RTPDynamicProtocolHandler ff_vp8_dynamic_handler = { - .enc_name = "VP8", - .codec_type = AVMEDIA_TYPE_VIDEO, - .codec_id = AV_CODEC_ID_VP8, - .alloc = vp8_new_context, - .free = vp8_free_context, - .parse_packet = vp8_handle_packet, - .need_keyframe = vp8_need_keyframe, -}; |
