[FFmpeg-soc] [soc]: r4482 - rtmp/rtmpdec.c

kostya subversion at mplayerhq.hu
Thu Jun 18 06:37:40 CEST 2009


Author: kostya
Date: Thu Jun 18 06:37:40 2009
New Revision: 4482

Log:
Call packet parsing from FLV instead of using copypasted code

Modified:
   rtmp/rtmpdec.c

Modified: rtmp/rtmpdec.c
==============================================================================
--- rtmp/rtmpdec.c	Thu Jun 18 06:35:26 2009	(r4481)
+++ rtmp/rtmpdec.c	Thu Jun 18 06:37:40 2009	(r4482)
@@ -49,6 +49,10 @@ typedef struct RTMPState {
     char playpath[256];
     ClientState state;
     int main_stream_id;
+    uint8_t *flv_data;
+    int flv_size;
+    ByteIOContext pb;
+    int wrong_dts;
 } RTMPState;
 
 #define PLAYER_KEY_OPEN_PART_LEN 30
@@ -419,6 +423,7 @@ static int rtmp_read_header(AVFormatCont
     st->codec->codec_type = CODEC_TYPE_AUDIO;
     av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
 
+    init_put_byte(&rt->pb, NULL, 0, 0, NULL, NULL, NULL, NULL);
     return 0;
 }
 
@@ -534,15 +539,15 @@ static int rtmp_parse_result(AVFormatCon
 static int rtmp_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     RTMPState *rt = s->priv_data;
-    AVStream *st = NULL;
     struct timespec ts;
-    int i, ret;
+    int ret;
 
     ts.tv_sec = 0;
     ts.tv_nsec = 500000000;
-    for (;;) {
+
+    while (url_ftell(&rt->pb) == rt->flv_size) {
         RTMPPacket rpkt;
-        int i;
+        int has_data = 0;
         if ((ret = rtmp_packet_read(s, rt->rtmp_hd, &rpkt, &rt->rhist)) != 0) {
             if (ret > 0) {
                 nanosleep(&ts, NULL);
@@ -557,73 +562,47 @@ static int rtmp_read_packet(AVFormatCont
             rtmp_packet_destroy(&rpkt);
             return -1;
         }
+        if (!rpkt.data_size) {
+            rtmp_packet_destroy(&rpkt);
+            continue;
+        }
+        if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO || rpkt.type == RTMP_PT_NOTIFY) {
+            uint8_t *p;
 
-        if (rpkt.type == RTMP_PT_CHUNK_SIZE)
-            for(i=0;i<RTMP_CHANNELS;i++)rt->rhist.chunk_size[i/*rpkt.stream_id*/] = AV_RB32(rpkt.data);
-        if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
-            int is_audio = rpkt.type == RTMP_PT_AUDIO;
-            int flags;
-            int off = 1;
-
-            flags = rpkt.data[0];
-            for (i = 0; i < s->nb_streams; i++) {
-                st = s->streams[i];
-                if (st->id == is_audio)
-                    break;
-            }
-            if (is_audio && (!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample)) {
-                st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
-                st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
-                st->codec->bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
-            }
-            if (!st->codec->codec_id) {
-                if (is_audio)
-                    flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK);
-                else
-                    flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK);
-            }
-            if (st->codec->codec_id == CODEC_ID_AAC ||
-                st->codec->codec_id == CODEC_ID_H264) {
-                int type = rpkt.data[off++];
-
-                if (st->codec->codec_id == CODEC_ID_H264) {
-                    off += 3;
-                }
-                if (!type) {
-                    av_free(st->codec->extradata);
-                    st->codec->extradata = av_mallocz(rpkt.data_size - off + FF_INPUT_BUFFER_PADDING_SIZE);
-                    if (!st->codec->extradata) {
-                        av_log(s, AV_LOG_ERROR, "Cannot allocate extradata\n");
-                        return AVERROR(ENOMEM);
-                    }
-                    st->codec->extradata_size = rpkt.data_size - off;
-                    memcpy(st->codec->extradata, rpkt.data + off, rpkt.data_size - off);
-                    rtmp_packet_destroy(&rpkt);
-                    continue;
-                }
-            }
-            if (off < rpkt.data_size) {
-                if (av_new_packet(pkt, rpkt.data_size - off) < 0) {
-                    rtmp_packet_destroy(&rpkt);
-                    return -1;
-                }
-                memcpy(pkt->data, rpkt.data + off, rpkt.data_size - off);
-                pkt->stream_index = st->index;
-                //pkt->pts = rpkt.timestamp;
-                rtmp_packet_destroy(&rpkt);
-
-                return pkt->size;
-            }
+            rt->flv_size = rpkt.data_size + 15;
+            rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
+            bytestream_put_be32(&p, 0);
+            bytestream_put_byte(&p, rpkt.type);
+            bytestream_put_be24(&p, rpkt.data_size);
+            bytestream_put_be24(&p, rpkt.extra);
+            bytestream_put_byte(&p, rpkt.extra >> 24);
+            bytestream_put_be24(&p, 0);
+            bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
+            has_data = 1;
+        } else if (rpkt.type == RTMP_PT_METADATA) {
+            rt->flv_size = rpkt.data_size + 4;
+            rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
+            memset(rt->flv_data, 0, 4); //previous packet size
+            memcpy(rt->flv_data + 4, rpkt.data, rpkt.data_size);
+            has_data = 1;
         }
         rtmp_packet_destroy(&rpkt);
+        if (has_data) {
+            init_put_byte(&rt->pb, rt->flv_data, rt->flv_size, 0, NULL, NULL, NULL, NULL);
+            break;
+        }
     }
-    return AVERROR(EIO);
+    ret = ff_flv_read_packet(s, &rt->pb, pkt, &rt->wrong_dts);
+    if (ret == AVERROR_EOF)
+        return AVERROR(EAGAIN);
+    return ret;
 }
 
 static int rtmp_read_close(AVFormatContext *s)
 {
     RTMPState *rt = s->priv_data;
 
+    av_freep(&rt->flv_data);
     url_close(rt->rtmp_hd);
     return 0;
 }


More information about the FFmpeg-soc mailing list