Merge commit '35c6ce76b107225a19eb33aea38857d2405882af'
[ffmpeg.git] / libavformat / rtpdec_h261.c
index b902d2a..9f34889 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavcodec/get_bits.h"
 #include "avformat.h"
 #include "rtpdec_formats.h"
-#include "libavcodec/get_bits.h"
 
-#define RTP_H261_PAYLOAD_HEADER_SIZE                    4
+#define RTP_H261_PAYLOAD_HEADER_SIZE 4
 
 struct PayloadContext {
     AVIOContext *buf;
@@ -32,7 +32,7 @@ struct PayloadContext {
     uint32_t     timestamp;
 };
 
-static PayloadContext *h261_new_context(void)
+static av_cold PayloadContext *h261_new_context(void)
 {
     return av_mallocz(sizeof(PayloadContext));
 }
@@ -45,7 +45,7 @@ static void h261_free_dyn_buffer(AVIOContext **dyn_buf)
     *dyn_buf = NULL;
 }
 
-static void h261_free_context(PayloadContext *pl_ctx)
+static av_cold void h261_free_context(PayloadContext *pl_ctx)
 {
     /* return if context is invalid */
     if (!pl_ctx)
@@ -63,8 +63,6 @@ static void h261_free_context(PayloadContext *pl_ctx)
 static av_cold int h261_init(AVFormatContext *ctx, int st_index,
                              PayloadContext *data)
 {
-    //av_log(ctx, AV_LOG_DEBUG, "h261_init() for stream %d\n", st_index);
-
     if (st_index < 0)
         return 0;
 
@@ -73,47 +71,46 @@ static av_cold int h261_init(AVFormatContext *ctx, int st_index,
     return 0;
 }
 
-int ff_h261_handle_packet(AVFormatContext *ctx, PayloadContext *data,
-                          AVStream *st, AVPacket *pkt, uint32_t *timestamp,
-                          const uint8_t *buf, int len, uint16_t seq, int flags)
+static int h261_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_h261_ctx,
+                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                              const uint8_t *buf, int len, uint16_t seq,
+                              int flags)
 {
     int sbit, ebit, gobn, mbap, quant;
     int res;
 
-    //av_log(ctx, AV_LOG_DEBUG, "got h261 RTP packet with time: %u\n", timestamp);
-
-    /* drop data of previous packets in case of non-continuous (loss) packet stream */
-    if (data->buf && data->timestamp != *timestamp) {
-        h261_free_dyn_buffer(&data->buf);
+    /* drop data of previous packets in case of non-continuous (lossy) packet stream */
+    if (rtp_h261_ctx->buf && rtp_h261_ctx->timestamp != *timestamp) {
+        h261_free_dyn_buffer(&rtp_h261_ctx->buf);
+        rtp_h261_ctx->endbyte_bits = 0;
     }
 
-    /* sanity check for size of input packet */
-    if (len < 5 /* 4 bytes header and 1 byte payload at least */) {
-        av_log(ctx, AV_LOG_ERROR, "Too short H.261 RTP packet\n");
+    /* sanity check for size of input packet: 1 byte payload at least */
+    if (len < RTP_H261_PAYLOAD_HEADER_SIZE + 1) {
+        av_log(ctx, AV_LOG_ERROR, "Too short RTP/H.261 packet, got %d bytes\n", len);
         return AVERROR_INVALIDDATA;
     }
 
     /*
-      decode 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
-
-    */
+     * decode 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
+     */
     sbit  =  (buf[0] >> 5) & 0x07;
     ebit  =  (buf[0] >> 2) & 0x07;
     gobn  =  (buf[1] >> 4) & 0x0f;
@@ -125,14 +122,14 @@ int ff_h261_handle_packet(AVFormatContext *ctx, PayloadContext *data,
     len -= RTP_H261_PAYLOAD_HEADER_SIZE;
 
     /* start frame buffering with new dynamic buffer */
-    if (!data->buf) {
-        /* sanity check: a new frame starts with gobn=0, sbit=0, mbap=0, uqnat=0 */
-        if (!gobn  && !sbit && !mbap && !quant){
-            res = avio_open_dyn_buf(&data->buf);
+    if (!rtp_h261_ctx->buf) {
+        /* sanity check: a new frame starts with gobn=0, sbit=0, mbap=0, quant=0 */
+        if (!gobn && !sbit && !mbap && !quant) {
+            res = avio_open_dyn_buf(&rtp_h261_ctx->buf);
             if (res < 0)
                 return res;
             /* update the timestamp in the frame packet with the one from the RTP packet */
-            data->timestamp = *timestamp;
+            rtp_h261_ctx->timestamp = *timestamp;
         } else {
             /* frame not started yet, need more packets */
             return AVERROR(EAGAIN);
@@ -140,39 +137,39 @@ int ff_h261_handle_packet(AVFormatContext *ctx, PayloadContext *data,
     }
 
     /* do the "byte merging" at the boundaries of two consecutive frame fragments */
-    if (data->endbyte_bits || sbit) {
-        if (data->endbyte_bits == sbit) {
-            data->endbyte |= buf[0] & (0xff >> sbit);
-            data->endbyte_bits = 0;
+    if (rtp_h261_ctx->endbyte_bits || sbit) {
+        if (rtp_h261_ctx->endbyte_bits == sbit) {
+            rtp_h261_ctx->endbyte     |= buf[0] & (0xff >> sbit);
+            rtp_h261_ctx->endbyte_bits = 0;
             buf++;
             len--;
-            avio_w8(data->buf, data->endbyte);
+            avio_w8(rtp_h261_ctx->buf, rtp_h261_ctx->endbyte);
         } else {
             /* ebit/sbit values inconsistent, assuming packet loss */
             GetBitContext gb;
             init_get_bits(&gb, buf, len*8 - ebit);
             skip_bits(&gb, sbit);
-            if (data->endbyte_bits) {
-                data->endbyte |= get_bits(&gb, 8 - data->endbyte_bits);
-                avio_w8(data->buf, data->endbyte);
+            if (rtp_h261_ctx->endbyte_bits) {
+                rtp_h261_ctx->endbyte |= get_bits(&gb, 8 - rtp_h261_ctx->endbyte_bits);
+                avio_w8(rtp_h261_ctx->buf, rtp_h261_ctx->endbyte);
             }
             while (get_bits_left(&gb) >= 8)
-                avio_w8(data->buf, get_bits(&gb, 8));
-            data->endbyte_bits = get_bits_left(&gb);
-            if (data->endbyte_bits)
-                data->endbyte = get_bits(&gb, data->endbyte_bits) <<
-                                (8 - data->endbyte_bits);
+                avio_w8(rtp_h261_ctx->buf, get_bits(&gb, 8));
+            rtp_h261_ctx->endbyte_bits = get_bits_left(&gb);
+            if (rtp_h261_ctx->endbyte_bits)
+                rtp_h261_ctx->endbyte = get_bits(&gb, rtp_h261_ctx->endbyte_bits) <<
+                                        (8 - rtp_h261_ctx->endbyte_bits);
             ebit = 0;
-            len = 0;
+            len  = 0;
         }
     }
     if (ebit) {
         if (len > 0)
-            avio_write(data->buf, buf, len - 1);
-        data->endbyte_bits = 8 - ebit;
-        data->endbyte = buf[len - 1] & (0xff << ebit);
+            avio_write(rtp_h261_ctx->buf, buf, len - 1);
+        rtp_h261_ctx->endbyte_bits = 8 - ebit;
+        rtp_h261_ctx->endbyte      = buf[len - 1] & (0xff << ebit);
     } else {
-        avio_write(data->buf, buf, len);
+        avio_write(rtp_h261_ctx->buf, buf, len);
     }
 
     /* RTP marker bit means: last fragment of current frame was received;
@@ -181,12 +178,12 @@ int ff_h261_handle_packet(AVFormatContext *ctx, PayloadContext *data,
         return AVERROR(EAGAIN);
 
     /* write the completed last byte from the "byte merging" */
-    if (data->endbyte_bits)
-        avio_w8(data->buf, data->endbyte);
-    data->endbyte_bits = 0;
+    if (rtp_h261_ctx->endbyte_bits)
+        avio_w8(rtp_h261_ctx->buf, rtp_h261_ctx->endbyte);
+    rtp_h261_ctx->endbyte_bits = 0;
 
     /* close frame buffering and create resulting A/V packet */
-    res = ff_rtp_finalize_packet(pkt, &data->buf, st->index);
+    res = ff_rtp_finalize_packet(pkt, &rtp_h261_ctx->buf, st->index);
     if (res < 0)
         return res;
 
@@ -198,8 +195,8 @@ RTPDynamicProtocolHandler ff_h261_dynamic_handler = {
     .codec_type        = AVMEDIA_TYPE_VIDEO,
     .codec_id          = AV_CODEC_ID_H261,
     .init              = h261_init,
-    .parse_packet      = ff_h261_handle_packet,
     .alloc             = h261_new_context,
     .free              = h261_free_context,
+    .parse_packet      = h261_handle_packet,
     .static_payload_id = 31,
 };