| 226 | } |
| 227 | |
| 228 | butil::Status FlvReader::Read(RtmpVideoMessage* msg) { |
| 229 | char tags[11]; |
| 230 | const unsigned char* p = (const unsigned char*)_buf->fetch(tags, sizeof(tags)); |
| 231 | if (p == NULL) { |
| 232 | return butil::Status(EAGAIN, "Fail to read, not enough data"); |
| 233 | } |
| 234 | if (*p != FLV_TAG_VIDEO) { |
| 235 | return butil::Status(EINVAL, "Fail to parse RtmpVideoMessage"); |
| 236 | } |
| 237 | uint32_t msg_size = policy::ReadBigEndian3Bytes(p + 1); |
| 238 | uint32_t timestamp = policy::ReadBigEndian3Bytes(p + 4); |
| 239 | timestamp |= (*(p + 7) << 24); |
| 240 | if (_buf->length() < 11 + msg_size + 4/*PreviousTagSize*/) { |
| 241 | return butil::Status(EAGAIN, "Fail to read, not enough data"); |
| 242 | } |
| 243 | _buf->pop_front(11); |
| 244 | char first_byte = 0; |
| 245 | CHECK(_buf->cut1(&first_byte)); |
| 246 | msg->timestamp = timestamp; |
| 247 | msg->frame_type = (FlvVideoFrameType)((first_byte >> 4) & 0xF); |
| 248 | msg->codec = (FlvVideoCodec)(first_byte & 0xF); |
| 249 | // TODO(zhujiashun): check the validation of frame_type and codec |
| 250 | _buf->cutn(&msg->data, msg_size - 1); |
| 251 | _buf->pop_front(4/* PreviousTagSize0 */); |
| 252 | |
| 253 | return butil::Status::OK(); |
| 254 | } |
| 255 | |
| 256 | butil::Status FlvReader::Read(RtmpAudioMessage* msg) { |
| 257 | char tags[11]; |