/* 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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
/* 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);
}