Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-12-19 04:33:15 +0300
committerMichael Niedermayer <michaelni@gmx.at>2014-12-19 04:34:17 +0300
commit5162af67f41214edacefe05d9723e4a6d9847900 (patch)
treee07706bd952bc563e0b56adc26199675e19238d1 /libavformat/rtpenc_h261.c
parent3f5d1c8130b1326d779c4216886272a3efce816a (diff)
parenta505c0d7373336a4cc5aa2022111c46bdd388b1f (diff)
Merge commit 'a505c0d7373336a4cc5aa2022111c46bdd388b1f'
* commit 'a505c0d7373336a4cc5aa2022111c46bdd388b1f': rtp: Initial H.261 support Conflicts: Changelog libavformat/rtpdec_h261.c libavformat/rtpenc_h261.c libavformat/sdp.c libavformat/version.h See: 50a4d5cfc6749932347ee38c25b5040aea4b13a0 Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/rtpenc_h261.c')
-rw-r--r--libavformat/rtpenc_h261.c81
1 files changed, 63 insertions, 18 deletions
diff --git a/libavformat/rtpenc_h261.c b/libavformat/rtpenc_h261.c
index 6f63703f0a..9930b71473 100644
--- a/libavformat/rtpenc_h261.c
+++ b/libavformat/rtpenc_h261.c
@@ -22,36 +22,81 @@
#include "avformat.h"
#include "rtpenc.h"
-void ff_rtp_send_h261(AVFormatContext *s1, const uint8_t *frame_buf, int frame_size)
+#define RTP_H261_HEADER_SIZE 4
+
+static const uint8_t *find_resync_marker_reverse(const uint8_t *restrict start,
+ const uint8_t *restrict end)
+{
+ const uint8_t *p = end - 1;
+ start += 1; /* Make sure we never return the original start. */
+ for (; p > start; p--) {
+ if (p[0] == 0 && p[1] == 1)
+ return p;
+ }
+ return end;
+}
+
+void ff_rtp_send_h261(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size)
{
- RTPMuxContext *rtp_ctx = s1->priv_data;
- int processed_frame_size;
+ int cur_frame_size;
int last_packet_of_frame;
- uint8_t *tmp_buf_ptr;
+ RTPMuxContext *rtp_ctx = ctx->priv_data;
/* use the default 90 KHz time stamp */
rtp_ctx->timestamp = rtp_ctx->cur_timestamp;
/* continue as long as not all frame data is processed */
while (frame_size > 0) {
- tmp_buf_ptr = rtp_ctx->buf;
- *tmp_buf_ptr++ = 1; /* V=1 */
- *tmp_buf_ptr++ = 0;
- *tmp_buf_ptr++ = 0;
- *tmp_buf_ptr++ = 0;
-
- processed_frame_size = FFMIN(rtp_ctx->max_payload_size - 4, frame_size);
+ /*
+ * encode the H.261 payload header according to section 4.1 of RFC 4587:
+ * (uses 4 bytes between RTP header and H.261 stream per packet)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |SBIT |EBIT |I|V| GOBN | MBAP | QUANT | HMVD | VMVD |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Start bit position (SBIT): 3 bits
+ * End bit position (EBIT): 3 bits
+ * INTRA-frame encoded data (I): 1 bit
+ * Motion Vector flag (V): 1 bit
+ * GOB number (GOBN): 4 bits
+ * Macroblock address predictor (MBAP): 5 bits
+ * Quantizer (QUANT): 5 bits
+ * Horizontal motion vector data (HMVD): 5 bits
+ * Vertical motion vector data (VMVD): 5 bits
+ */
+ rtp_ctx->buf[0] = 1; /* sbit=0, ebit=0, i=0, v=1 */
+ rtp_ctx->buf[1] = 0; /* gobn=0, mbap=0 */
+ rtp_ctx->buf[2] = 0; /* quant=0, hmvd=5 */
+ rtp_ctx->buf[3] = 0; /* vmvd=0 */
+ if (frame_size < 2 || frame_buf[0] != 0 || frame_buf[1] != 1) {
+ /* A full, correct fix for this would be to make the H261 encoder
+ * support inserting extra GOB headers (triggered by setting e.g.
+ * "-ps 1"), and including information about macroblock boundaries
+ * (such as for h263_rfc2190). */
+ av_log(ctx, AV_LOG_WARNING,
+ "RTP/H261 packet not cut at a GOB boundary, not signaled correctly\n");
+ }
- //XXX: parse the h.261 bitstream and improve frame splitting here
+ cur_frame_size = FFMIN(rtp_ctx->max_payload_size - RTP_H261_HEADER_SIZE, frame_size);
- last_packet_of_frame = (processed_frame_size == frame_size);
+ /* look for a better place to split the frame into packets */
+ if (cur_frame_size < frame_size) {
+ const uint8_t *packet_end = find_resync_marker_reverse(frame_buf,
+ frame_buf + cur_frame_size);
+ cur_frame_size = packet_end - frame_buf;
+ }
- memcpy(tmp_buf_ptr, frame_buf, processed_frame_size);
- tmp_buf_ptr += processed_frame_size;
+ /* calculate the "marker" bit for the RTP header */
+ last_packet_of_frame = cur_frame_size == frame_size;
- ff_rtp_send_data(s1, rtp_ctx->buf, tmp_buf_ptr - rtp_ctx->buf, last_packet_of_frame);
+ /* complete and send RTP packet */
+ memcpy(&rtp_ctx->buf[RTP_H261_HEADER_SIZE], frame_buf, cur_frame_size);
+ ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_H261_HEADER_SIZE + cur_frame_size, last_packet_of_frame);
- frame_buf += processed_frame_size;
- frame_size -= processed_frame_size;
+ frame_buf += cur_frame_size;
+ frame_size -= cur_frame_size;
}
}