private void fillMessage(Message message, int cseq, RtspHeader[] extras) {

    message.addHeader(new CSeqHeader(cseq));
    for (RtspHeader h : extras) {
      message.addHeader(h);
    }
  }
  /*
   * This method handles RTSP server responses
   * */
  public void incomingMessage(MessageBuffer buffer) throws Exception {

    // read a message bytes data in buffer
    ByteArrayInputStream in =
        new ByteArrayInputStream(buffer.getData(), buffer.getOffset(), buffer.getLength());

    int initial = in.available();
    Message message = null;

    try {
      String line = readLine(in);
      if (line.startsWith(Message.RTSP_TOKEN)) {
        message = new RtspResponse(line);
      } else {
        RtspRequest.Method method = null;
        try {
          method = RtspRequest.Method.valueOf(line.substring(0, line.indexOf(' ')));
        } catch (IllegalArgumentException ilae) {

        }
        // 从Map中取出相应类型的Request信息
        Class<? extends RtspRequest> cls = requestMap.get(method);
        if (cls != null) message = cls.getConstructor(String.class).newInstance(line);
        else message = new RtspRequest(line);
      }

      while (true) {
        line = readLine(in);
        if (in == null) throw new Exception();
        if (line.length() == 0) break;
        Constructor<? extends RtspHeader> c =
            headerMap.get(line.substring(0, line.indexOf(':')).toLowerCase());
        if (c != null) message.addHeader(c.newInstance(line));
        else message.addHeader(new RtspHeader(line));
      }
      buffer.setMessage(message);

      try {
        int length = ((ContentLengthHeader) message.getHeader(ContentLengthHeader.NAME)).getValue();
        if (in.available() < length) throw new Exception();
        RtspContent content = new RtspContent();
        content.setDescription(message);
        byte[] data = new byte[length];
        in.read(data);
        content.setBytes(data);
        message.setEntityMessage(new RtspEntityMessage(message, content));
      } catch (Exception e) {
        e.printStackTrace();
      }
    } catch (Exception e) {
      throw new Exception(e);
    } finally {
      // TODO:读取后更新buffer状态
      buffer.setused(initial - in.available());
      // buffer.discardData();

      try {
        in.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }