OSDN Git Service

FLV配信用パッチをマージ。(github:niwakazoider/peercast@21998fef7e24f437ef8d50e17562ba95eb5c1843)
[peercast-im/PeerCastIM.git] / core / common / flv.cpp
1 // ------------------------------------------------
2 // File : flv.cpp
3 // Date: 14-jan-2017
4 // Author: niwakazoider
5 //
6 // Modified by Eru @2017.1.15 for compilation error at VS2008
7 //
8 // (c) 2002-3 peercast.org
9 // ------------------------------------------------
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 // ------------------------------------------------
20
21 #include "channel.h"
22 #include "flv.h"
23 #include "string.h"
24 #include "stdio.h"
25 #ifdef _DEBUG
26 #include "chkMemoryLeak.h"
27 #define DEBUG_NEW new(__FILE__, __LINE__)
28 #define new DEBUG_NEW
29 #endif
30
31
32 // ------------------------------------------
33 void FLVStream::readEnd(Stream &, Channel *)
34 {
35 }
36
37 // ------------------------------------------
38 void FLVStream::readHeader(Stream &, Channel *)
39 {
40 }
41
42 // ------------------------------------------
43 int FLVStream::readPacket(Stream &in, Channel *ch)
44 {
45         bool headerUpdate = false;
46
47         if (ch->streamPos == 0) {
48                 bitrate = 0;
49                 FLVFileHeader header = FLVFileHeader();
50                 header.read(in);
51                 fileHeader = header;
52                 headerUpdate = true;
53         }
54
55         FLVTag flvTag;
56         flvTag.read(in);
57         
58         switch (flvTag.type)
59         {
60                 case TAG_SCRIPTDATA:
61                 {
62                         AMFObject amf;
63                         MemoryStream flvmem = MemoryStream(flvTag.data, flvTag.size);
64                         if (amf.readMetaData(flvmem)) {
65                                 flvmem.close();
66                                 bitrate = amf.bitrate;
67                                 metaData = flvTag;
68                                 headerUpdate = true;
69                         }
70                 }
71                 case TAG_VIDEO:
72                 {
73                         //AVC Header
74                         if (flvTag.data[0] == 0x17 && flvTag.data[1] == 0x00 &&
75                                 flvTag.data[2] == 0x00 && flvTag.data[3] == 0x00) {
76                                 avcHeader = flvTag;
77                                 headerUpdate = true;
78                         }
79                 }
80                 case TAG_AUDIO:
81                 {
82                         //AAC Header
83                         if (flvTag.data[0] == 0xaf && flvTag.data[1] == 0x00) {
84                                 aacHeader = flvTag;
85                                 headerUpdate = true;
86                         }
87                 }
88         }
89         
90         if (headerUpdate && fileHeader.size>0) {
91                 int len = fileHeader.size;
92                 if (metaData.type==TAG_SCRIPTDATA) len += metaData.packetSize;
93                 if (avcHeader.type == TAG_VIDEO) len += avcHeader.packetSize;
94                 if (aacHeader.type == TAG_AUDIO) len += aacHeader.packetSize;
95                 MemoryStream mem = MemoryStream(ch->headPack.data, len);
96                 mem.write(fileHeader.data, fileHeader.size);
97                 if (metaData.type == TAG_SCRIPTDATA) mem.write(metaData.packet, metaData.packetSize);
98                 if (avcHeader.type == TAG_VIDEO) mem.write(avcHeader.packet, avcHeader.packetSize);
99                 if (aacHeader.type == TAG_AUDIO) mem.write(aacHeader.packet, aacHeader.packetSize);
100
101                 ch->info.bitrate = bitrate;
102
103                 ch->headPack.type = ChanPacket::T_HEAD;
104                 ch->headPack.len = mem.pos;
105                 ch->headPack.pos = ch->streamPos;
106                 ch->newPacket(ch->headPack);
107
108                 ch->streamPos += ch->headPack.len;
109         }
110         else {
111                 ChanPacket pack;
112
113                 MemoryStream mem = MemoryStream(flvTag.packet, flvTag.packetSize);
114
115                 int rlen = flvTag.packetSize;
116                 while (rlen)
117                 {
118                         int rl = rlen;
119                         if (rl > ChanMgr::MAX_METAINT)
120                                 rl = ChanMgr::MAX_METAINT;
121
122                         pack.init(ChanPacket::T_DATA, pack.data, rl, ch->streamPos);
123                         mem.read(pack.data, pack.len);
124                         ch->newPacket(pack);
125                         ch->checkReadDelay(pack.len);
126                         ch->streamPos += pack.len;
127
128                         rlen -= rl;
129                 }
130
131                 mem.close();
132                 
133         }
134         
135         return 0;
136 }