/* SRT format: * Subtitle number * Start time --> End time * Text of subtitle (one or more lines) * Blank lines * * .srt file example: * 1 * 00:00:20,000 --> 00:00:24,400 * Altocumulus clouds occr between six thousand * * 2 * 00:00:24,600 --> 00:00:27,800 * and twenty thousand feet above ground level. */ status_t TimedTextSRTSource::getNextSubtitleInfo( off64_t *offset, int64_t *startTimeUs, TextInfo *info) { AString data; status_t err; // To skip blank lines. do { if ((err = readNextLine(offset, &data)) != OK) { return err; } data.trim(); } while (data.empty()); // Just ignore the first non-blank line which is subtitle sequence number. if ((err = readNextLine(offset, &data)) != OK) { return err; } int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2; // the start time format is: hours:minutes:seconds,milliseconds // 00:00:24,600 --> 00:00:27,800 if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d", &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) { return ERROR_MALFORMED; } *startTimeUs = ((hour1 * 3600 + min1 * 60 + sec1) * 1000 + msec1) * 1000ll; info->endTimeUs = ((hour2 * 3600 + min2 * 60 + sec2) * 1000 + msec2) * 1000ll; if (info->endTimeUs <= *startTimeUs) { return ERROR_MALFORMED; } info->offset = *offset; bool needMoreData = true; while (needMoreData) { if ((err = readNextLine(offset, &data)) != OK) { if (err == ERROR_END_OF_STREAM) { break; } else { return err; } } data.trim(); if (data.empty()) { // it's an empty line used to separate two subtitles needMoreData = false; } } info->textLen = *offset - info->offset; return OK; }
// static status_t M3UParser::parseByteRange( const AString &line, uint64_t curOffset, uint64_t *length, uint64_t *offset) { ssize_t colonPos = line.find(":"); if (colonPos < 0) { return ERROR_MALFORMED; } ssize_t atPos = line.find("@", colonPos + 1); AString lenStr; if (atPos < 0) { lenStr = AString(line, colonPos + 1, line.size() - colonPos - 1); } else { lenStr = AString(line, colonPos + 1, atPos - colonPos - 1); } lenStr.trim(); const char *s = lenStr.c_str(); char *end; *length = strtoull(s, &end, 10); if (s == end || *end != '\0') { return ERROR_MALFORMED; } if (atPos >= 0) { AString offStr = AString(line, atPos + 1, line.size() - atPos - 1); offStr.trim(); const char *s = offStr.c_str(); *offset = strtoull(s, &end, 10); if (s == end || *end != '\0') { return ERROR_MALFORMED; } } else { *offset = curOffset; } return OK; }
bool ARTSPConnection::receiveRTSPRequest() { AString requestLine; LOGI(LOG_TAG,"start receiveLine ......\n"); if (!receiveLine(&requestLine)) { return false; } // LOGI(LOG_TAG,"receiveLine OK\n"); sp<AMessage> request = new AMessage(kWhatRequest,mhandlerID); request->setInt32("SessionID",mSessionID); LOGI(LOG_TAG,"request->setInt32 SessionID %d\n",mSessionID); LOGI(LOG_TAG,"request: %s\n", requestLine.c_str()); ssize_t space1 = requestLine.find(" ");//寻找空格 if (space1 < 0) { return false; } ssize_t space2 = requestLine.find(" ", space1 + 1); if (space2 < 0) { return false; } AString Method(requestLine.c_str(), space1); request->setString("Method",Method.c_str()); AString URI(requestLine,space1+1,space2-space1-1); request->setString("URI",URI.c_str()); AString line; for (;;) { if (!receiveLine(&line)) { break; } if (line.empty()) { break; } ssize_t colonPos = line.find(":"); if (colonPos < 0) { // Malformed header line. return false; } AString key(line, 0, colonPos); key.trim(); // key.tolower(); line.erase(0, colonPos + 1); line.trim(); LOGI(LOG_TAG,"line: %s:%s\n", key.c_str(),line.c_str()); request->setString(key.c_str(),line.c_str()); } LOGI(LOG_TAG,"Post the request to handler\n"); request->post();//将请求消息发送给uplayer 处理 return OK; }
/* SRT format: * Subtitle number * Start time --> End time * Text of subtitle (one or more lines) * Blank lines * * .srt file example: * 1 * 00:00:20,000 --> 00:00:24,400 * Altocumulus clouds occr between six thousand * * 2 * 00:00:24,600 --> 00:00:27,800 * and twenty thousand feet above ground level. */ status_t TimedTextSRTSource::getNextSubtitleInfo( off64_t *offset, int64_t *startTimeUs, TextInfo *info) { #ifdef MTK_SUBTITLE_SUPPORT MagicString data("", mFileEncodeType); MagicString* spString = new MagicString("-->", ENCODE_TYPE_NORMAL); int8_t typeSize = MagicString::sizeOfType(data.getType()); status_t err; // To skip blank lines. do { if ((err = TimedTextUtil::readNextLine(mSource, offset, &data, mFileEncodeType)) != OK) { ALOGE("[SRT Parser] Reading Over Return Here! (EOS)"); return err; } data.trim(); MagicString::print("[Get Line]", data); } while (data.empty()); MagicString::print("[Subtitle Index]", data); // Just ignore the first non-blank line which is subtitle sequence number. if ((err = TimedTextUtil::readNextLine(mSource, offset, &data, mFileEncodeType)) != OK) { return err; } MagicString::print("[Time Line]",data); int64_t index = data.indexOf(spString); if(-1 == index || 0 == index){ return ERROR_MALFORMED; } sp<MagicString> time1 = data.subString(0, index - typeSize); time1->trim(); MagicString::print("[StartTime]", time1); sp<MagicString> time2 = data.subString(index + spString->length() * typeSize); time2->trim(); MagicString::print("[EndTime]", time2); // the start time format is: hours:minutes:seconds,milliseconds // 00:00:24,600 --> 00:00:27,800 StructTime startTime = StructTime(time1); StructTime endTime = StructTime(time2); *startTimeUs = startTime.calcTimeUs(); info->endTimeUs = endTime.calcTimeUs(); free(spString); ALOGE("[SRTParser] getStartTime=%lld, getEndTime=%lld", *startTimeUs, info->endTimeUs); if (info->endTimeUs <= *startTimeUs) { return ERROR_MALFORMED; } info->offset = *offset; bool needMoreData = true; int64_t lineBeginIndex = 0; int64_t lineLen = 0; while (needMoreData) { lineBeginIndex = *offset; if ((err = TimedTextUtil::readNextLine(mSource, offset, &data, mFileEncodeType)) != OK) { if (err == ERROR_END_OF_STREAM) { break; } else { return err; } } lineLen = data.length(); data.trim(); MagicString::print("[Get Subtitle]", data); if (data.empty()) { // it's an empty line used to separate two subtitles needMoreData = false; }else{ info->textLen = lineBeginIndex + lineLen - info->offset; //ALOGE("[SRT Parser] read a subtitle line begin=%lld, lineLen =%lld, end=%d", lineBeginIndex, lineLen, info->textLen); } } //ALOGE("[SRT Parser] subtitle from=%lld, len=%d", info->offset, info->textLen); return OK; #else AString data; status_t err; // To skip blank lines. do { if ((err = readNextLine(offset, &data)) != OK) { return err; } data.trim(); } while (data.empty()); // Just ignore the first non-blank line which is subtitle sequence number. if ((err = readNextLine(offset, &data)) != OK) { return err; } int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2; // the start time format is: hours:minutes:seconds,milliseconds // 00:00:24,600 --> 00:00:27,800 if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d", &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) { return ERROR_MALFORMED; } *startTimeUs = ((hour1 * 3600 + min1 * 60 + sec1) * 1000 + msec1) * 1000ll; info->endTimeUs = ((hour2 * 3600 + min2 * 60 + sec2) * 1000 + msec2) * 1000ll; if (info->endTimeUs <= *startTimeUs) { return ERROR_MALFORMED; } info->offset = *offset; bool needMoreData = true; while (needMoreData) { if ((err = readNextLine(offset, &data)) != OK) { if (err == ERROR_END_OF_STREAM) { break; } else { return err; } } data.trim(); if (data.empty()) { // it's an empty line used to separate two subtitles needMoreData = false; } } info->textLen = *offset - info->offset; return OK; #endif }
bool ARTSPConnection::receiveRTSPReponse() { AString statusLine; if (!receiveLine(&statusLine)) { return false; } if (statusLine == "$") { sp<ABuffer> buffer = receiveBinaryData(); if (buffer == NULL) { return false; } if (mObserveBinaryMessage != NULL) { sp<AMessage> notify = mObserveBinaryMessage->dup(); notify->setObject("buffer", buffer); notify->post(); } else { LOGW("received binary data, but no one cares."); } return true; } sp<ARTSPResponse> response = new ARTSPResponse; response->mStatusLine = statusLine; LOGI("status: %s", response->mStatusLine.c_str()); ssize_t space1 = response->mStatusLine.find(" "); if (space1 < 0) { return false; } ssize_t space2 = response->mStatusLine.find(" ", space1 + 1); if (space2 < 0) { return false; } AString statusCodeStr( response->mStatusLine, space1 + 1, space2 - space1 - 1); if (!ParseSingleUnsignedLong( statusCodeStr.c_str(), &response->mStatusCode) || response->mStatusCode < 100 || response->mStatusCode > 999) { return false; } AString line; for (;;) { if (!receiveLine(&line)) { break; } if (line.empty()) { break; } LOGV("line: %s", line.c_str()); ssize_t colonPos = line.find(":"); if (colonPos < 0) { // Malformed header line. return false; } AString key(line, 0, colonPos); key.trim(); key.tolower(); line.erase(0, colonPos + 1); line.trim(); response->mHeaders.add(key, line); } unsigned long contentLength = 0; ssize_t i = response->mHeaders.indexOfKey("content-length"); if (i >= 0) { AString value = response->mHeaders.valueAt(i); if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) { return false; } } if (contentLength > 0) { response->mContent = new ABuffer(contentLength); size_t numBytesRead = 0; while (numBytesRead < contentLength) { ssize_t n = recv( mSocket, response->mContent->data() + numBytesRead, contentLength - numBytesRead, 0); if (n == 0) { // Server closed the connection. TRESPASS(); } else if (n < 0) { if (errno == EINTR) { continue; } TRESPASS(); } numBytesRead += (size_t)n; } } return notifyResponseListener(response); }
bool ARTSPConnection::receiveRTSPReponse() { AString statusLine; if (!receiveLine(&statusLine)) { return false; } if (statusLine == "$") { sp<ABuffer> buffer = receiveBinaryData(); if (buffer == NULL) { return false; } if (mObserveBinaryMessage != NULL) { sp<AMessage> notify = mObserveBinaryMessage->dup(); notify->setObject("buffer", buffer); notify->post(); } else { LOGW("received binary data, but no one cares."); } return true; } sp<ARTSPResponse> response = new ARTSPResponse; response->mStatusLine = statusLine; LOGI("status: %s", response->mStatusLine.c_str()); ssize_t space1 = response->mStatusLine.find(" "); if (space1 < 0) { return false; } ssize_t space2 = response->mStatusLine.find(" ", space1 + 1); if (space2 < 0) { return false; } AString statusCodeStr( response->mStatusLine, space1 + 1, space2 - space1 - 1); if (!ParseSingleUnsignedLong( statusCodeStr.c_str(), &response->mStatusCode) || response->mStatusCode < 100 || response->mStatusCode > 999) { return false; } AString line; for (;;) { if (!receiveLine(&line)) { break; } if (line.empty()) { break; } LOGV("line: %s", line.c_str()); ssize_t colonPos = line.find(":"); if (colonPos < 0) { // Malformed header line. return false; } AString key(line, 0, colonPos); key.trim(); key.tolower(); line.erase(0, colonPos + 1); line.trim(); response->mHeaders.add(key, line); } unsigned long contentLength = 0; ssize_t i = response->mHeaders.indexOfKey("content-length"); if (i >= 0) { AString value = response->mHeaders.valueAt(i); if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) { return false; } } if (contentLength > 0) { response->mContent = new ABuffer(contentLength); size_t numBytesRead = 0; while (numBytesRead < contentLength) { ssize_t n = recv( mSocket, response->mContent->data() + numBytesRead, contentLength - numBytesRead, 0); if (n == 0) { // Server closed the connection. TRESPASS(); } else if (n < 0) { if (errno == EINTR) { continue; } TRESPASS(); } numBytesRead += (size_t)n; } } if (response->mStatusCode == 401) { if (mAuthType == NONE && mUser.size() > 0 && parseAuthMethod(response)) { ssize_t i; CHECK_EQ((status_t)OK, findPendingRequest(response, &i)); CHECK_GE(i, 0); sp<AMessage> reply = mPendingRequests.valueAt(i); mPendingRequests.removeItemsAt(i); AString request; CHECK(reply->findString("original-request", &request)); sp<AMessage> msg = new AMessage(kWhatSendRequest, id()); msg->setMessage("reply", reply); msg->setString("request", request.c_str(), request.size()); LOGI("re-sending request with authentication headers..."); onSendRequest(msg); return true; } } return notifyResponseListener(response); }