]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/rtpdec_qt.c
lavf: replace AVStream.codec with AVStream.codecpar
[ffmpeg] / libavformat / rtpdec_qt.c
index 4d8437e947b58cbbdf8a360fb3800f35ed18996a..9566c3d311d2e6cad65506ebfb389f325c6b01e0 100644 (file)
@@ -2,20 +2,20 @@
  * RTP/Quicktime support.
  * Copyright (c) 2009 Ronald S. Bultje
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav 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,
+ * Libav 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
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,8 @@
  */
 
 #include "avformat.h"
+#include "internal.h"
+#include "avio_internal.h"
 #include "rtp.h"
 #include "rtpdec.h"
 #include "isom.h"
@@ -40,12 +42,13 @@ struct PayloadContext {
 static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
                                AVStream *st, AVPacket *pkt,
                                uint32_t *timestamp, const uint8_t *buf,
-                               int len, int flags)
+                               int len, uint16_t seq, int flags)
 {
-    ByteIOContext pb;
+    AVIOContext pb;
     GetBitContext gb;
     int packing_scheme, has_payload_desc, has_packet_info, alen,
-        has_marker_bit = flags & RTP_FLAG_MARKER;
+        has_marker_bit = flags & RTP_FLAG_MARKER,
+        keyframe;
 
     if (qt->remaining) {
         int num = qt->pkt.size / qt->bytes_per_frame;
@@ -69,7 +72,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
      * http://developer.apple.com/quicktime/icefloe/dispatch026.html
      */
     init_get_bits(&gb, buf, len << 3);
-    init_put_byte(&pb, buf, len, 0, NULL, NULL, NULL, NULL);
+    ffio_init_context(&pb, buf, len, 0, NULL, NULL, NULL, NULL);
 
     if (len < 4)
         return AVERROR_INVALIDDATA;
@@ -77,8 +80,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
     skip_bits(&gb, 4); // version
     if ((packing_scheme = get_bits(&gb, 2)) == 0)
         return AVERROR_INVALIDDATA;
-    if (get_bits1(&gb))
-        flags          |= RTP_FLAG_KEY;
+    keyframe            = get_bits1(&gb);
     has_payload_desc    = get_bits1(&gb);
     has_packet_info     = get_bits1(&gb);
     skip_bits(&gb, 23); // reserved:7, cache payload info:1, payload ID:15
@@ -95,29 +97,29 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
         is_start  = get_bits1(&gb);
         is_finish = get_bits1(&gb);
         if (!is_start || !is_finish) {
-            av_log_missing_feature(s, "RTP-X-QT with payload description "
-                                      "split over several packets", 1);
-            return AVERROR_NOTSUPP;
+            avpriv_request_sample(s, "RTP-X-QT with payload description "
+                                  "split over several packets");
+            return AVERROR_PATCHWELCOME;
         }
         skip_bits(&gb, 12); // reserved
         data_len = get_bits(&gb, 16);
 
-        url_fseek(&pb, pos + 4, SEEK_SET);
-        tag = get_le32(&pb);
-        if ((st->codec->codec_type == CODEC_TYPE_VIDEO &&
+        avio_seek(&pb, pos + 4, SEEK_SET);
+        tag = avio_rl32(&pb);
+        if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
                  tag != MKTAG('v','i','d','e')) ||
-            (st->codec->codec_type == CODEC_TYPE_AUDIO &&
+            (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
                  tag != MKTAG('s','o','u','n')))
             return AVERROR_INVALIDDATA;
-        av_set_pts_info(st, 32, 1, get_be32(&pb));
+        avpriv_set_pts_info(st, 32, 1, avio_rb32(&pb));
 
         if (pos + data_len > len)
             return AVERROR_INVALIDDATA;
         /* TLVs */
-        while (url_ftell(&pb) + 4 < pos + data_len) {
-            int tlv_len = get_be16(&pb);
-            tag = get_le16(&pb);
-            if (url_ftell(&pb) + tlv_len > pos + data_len)
+        while (avio_tell(&pb) + 4 < pos + data_len) {
+            int tlv_len = avio_rb16(&pb);
+            tag = avio_rl16(&pb);
+            if (avio_tell(&pb) + tlv_len > pos + data_len)
                 return AVERROR_INVALIDDATA;
 
 #define MKTAG16(a,b) MKTAG(a,b,0,0)
@@ -148,49 +150,55 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
                 break;
             }
             default:
-                url_fskip(&pb, tlv_len);
+                avio_skip(&pb, tlv_len);
                 break;
             }
         }
 
         /* 32-bit alignment */
-        url_fskip(&pb, ((url_ftell(&pb) + 3) & ~3) - url_ftell(&pb));
+        avio_skip(&pb, ((avio_tell(&pb) + 3) & ~3) - avio_tell(&pb));
     } else
-        url_fseek(&pb, 4, SEEK_SET);
+        avio_seek(&pb, 4, SEEK_SET);
 
     if (has_packet_info) {
-        av_log_missing_feature(s, "RTP-X-QT with packet specific info", 1);
-        return AVERROR_NOTSUPP;
+        avpriv_request_sample(s, "RTP-X-QT with packet-specific info");
+        return AVERROR_PATCHWELCOME;
     }
 
-    alen = len - url_ftell(&pb);
+    alen = len - avio_tell(&pb);
     if (alen <= 0)
         return AVERROR_INVALIDDATA;
 
     switch (packing_scheme) {
     case 3: /* one data packet spread over 1 or multiple RTP packets */
         if (qt->pkt.size > 0 && qt->timestamp == *timestamp) {
-            qt->pkt.data = av_realloc(qt->pkt.data, qt->pkt.size + alen +
-                                      FF_INPUT_BUFFER_PADDING_SIZE);
+            int err;
+            if ((err = av_reallocp(&qt->pkt.data, qt->pkt.size + alen +
+                                   AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+                qt->pkt.size = 0;
+                return err;
+            }
         } else {
             av_freep(&qt->pkt.data);
             av_init_packet(&qt->pkt);
-            qt->pkt.data = av_malloc(alen + FF_INPUT_BUFFER_PADDING_SIZE);
+            qt->pkt.data = av_realloc(NULL, alen + AV_INPUT_BUFFER_PADDING_SIZE);
+            if (!qt->pkt.data)
+                return AVERROR(ENOMEM);
             qt->pkt.size = 0;
             qt->timestamp = *timestamp;
         }
-        if (!qt->pkt.data)
-            return AVERROR(ENOMEM);
-        memcpy(qt->pkt.data + qt->pkt.size, buf + url_ftell(&pb), alen);
+        memcpy(qt->pkt.data + qt->pkt.size, buf + avio_tell(&pb), alen);
         qt->pkt.size += alen;
         if (has_marker_bit) {
-            *pkt = qt->pkt;
+            int ret = av_packet_from_data(pkt, qt->pkt.data, qt->pkt.size);
+            if (ret < 0)
+                return ret;
+
             qt->pkt.size = 0;
             qt->pkt.data = NULL;
-            pkt->flags        = flags & RTP_FLAG_KEY ? AV_PKT_FLAG_KEY : 0;
+            pkt->flags        = keyframe ? AV_PKT_FLAG_KEY : 0;
             pkt->stream_index = st->index;
-            pkt->destruct     = av_destruct_packet;
-            memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+            memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
             return 0;
         }
         return AVERROR(EAGAIN);
@@ -202,19 +210,19 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
         qt->remaining = (alen / qt->bytes_per_frame) - 1;
         if (av_new_packet(pkt, qt->bytes_per_frame))
             return AVERROR(ENOMEM);
-        memcpy(pkt->data, buf + url_ftell(&pb), qt->bytes_per_frame);
-        pkt->flags = flags & RTP_FLAG_KEY ? AV_PKT_FLAG_KEY : 0;
+        memcpy(pkt->data, buf + avio_tell(&pb), qt->bytes_per_frame);
+        pkt->flags = keyframe ? AV_PKT_FLAG_KEY : 0;
         pkt->stream_index = st->index;
         if (qt->remaining > 0) {
             av_freep(&qt->pkt.data);
-            qt->pkt.data = av_malloc(qt->remaining * qt->bytes_per_frame);
+            qt->pkt.data = av_realloc(NULL, qt->remaining * qt->bytes_per_frame);
             if (!qt->pkt.data) {
-                av_free_packet(pkt);
+                av_packet_unref(pkt);
                 return AVERROR(ENOMEM);
             }
             qt->pkt.size = qt->remaining * qt->bytes_per_frame;
             memcpy(qt->pkt.data,
-                   buf + url_ftell(&pb) + qt->bytes_per_frame,
+                   buf + avio_tell(&pb) + qt->bytes_per_frame,
                    qt->remaining * qt->bytes_per_frame);
             qt->pkt.flags = pkt->flags;
             return 1;
@@ -222,34 +230,27 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
         return 0;
 
     default:  /* unimplemented */
-        av_log_missing_feature(NULL, "RTP-X-QT with packing scheme 2", 1);
-        return AVERROR_NOTSUPP;
+        avpriv_request_sample(NULL, "RTP-X-QT with packing scheme 2");
+        return AVERROR_PATCHWELCOME;
     }
 }
 
-static PayloadContext *qt_rtp_new(void)
-{
-    return av_mallocz(sizeof(PayloadContext));
-}
-
-static void qt_rtp_free(PayloadContext *qt)
+static void qt_rtp_close(PayloadContext *qt)
 {
     av_freep(&qt->pkt.data);
-    av_free(qt);
 }
 
 #define RTP_QT_HANDLER(m, n, s, t) \
 RTPDynamicProtocolHandler ff_ ## m ## _rtp_ ## n ## _handler = { \
     .enc_name         = s, \
     .codec_type       = t, \
-    .codec_id         = CODEC_ID_NONE, \
-    .parse_sdp_a_line = NULL,          \
-    .open             = qt_rtp_new,    \
-    .close            = qt_rtp_free,   \
+    .codec_id         = AV_CODEC_ID_NONE, \
+    .priv_data_size   = sizeof(PayloadContext), \
+    .close            = qt_rtp_close,   \
     .parse_packet     = qt_rtp_parse_packet, \
-};
+}
 
-RTP_QT_HANDLER(qt,        vid, "X-QT",        CODEC_TYPE_VIDEO);
-RTP_QT_HANDLER(qt,        aud, "X-QT",        CODEC_TYPE_AUDIO);
-RTP_QT_HANDLER(quicktime, vid, "X-QUICKTIME", CODEC_TYPE_VIDEO);
-RTP_QT_HANDLER(quicktime, aud, "X-QUICKTIME", CODEC_TYPE_AUDIO);
+RTP_QT_HANDLER(qt,        vid, "X-QT",        AVMEDIA_TYPE_VIDEO);
+RTP_QT_HANDLER(qt,        aud, "X-QT",        AVMEDIA_TYPE_AUDIO);
+RTP_QT_HANDLER(quicktime, vid, "X-QUICKTIME", AVMEDIA_TYPE_VIDEO);
+RTP_QT_HANDLER(quicktime, aud, "X-QUICKTIME", AVMEDIA_TYPE_AUDIO);