Loading media/libmediaplayer2/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ cc_library { "libprotobuf-cpp-lite", "libstagefright_nuplayer2", "libstagefright_rtsp", "libstagefright_timedtext", "libstagefright_timedtext2", ], export_include_dirs: [ Loading media/libmediaplayer2/nuplayer2/NuPlayer2.cpp +9 −10 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ #include "NuPlayer2Source.h" #include "RTSPSource2.h" #include "GenericSource2.h" #include "TextDescriptions.h" #include "TextDescriptions2.h" #include "ATSParser.h" Loading Loading @@ -2870,7 +2870,7 @@ void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) { const void *data; size_t size = 0; int64_t timeUs; int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP; int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP; AString mime; CHECK(buffer->meta()->findString("mime", &mime)); Loading @@ -2879,22 +2879,21 @@ void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) { data = buffer->data(); size = buffer->size(); Parcel parcel; PlayerMessage playerMsg; if (size > 0) { CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); int32_t global = 0; if (buffer->meta()->findInt32("global", &global) && global) { flag |= TextDescriptions::GLOBAL_DESCRIPTIONS; flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS; } else { flag |= TextDescriptions::LOCAL_DESCRIPTIONS; flag |= TextDescriptions2::LOCAL_DESCRIPTIONS; } TextDescriptions::getParcelOfDescriptions( (const uint8_t *)data, size, flag, timeUs / 1000, &parcel); TextDescriptions2::getPlayerMessageOfDescriptions( (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg); } if ((parcel.dataSize() > 0)) { // TODO: convert text data to PlayerMessage // notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &parcel); if (playerMsg.values_size() > 0) { notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg); } else { // send an empty timed text notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0); } Loading media/libstagefright/timedtext/Android.bp +33 −0 Original line number Diff line number Diff line Loading @@ -25,3 +25,36 @@ cc_library_static { shared_libs: ["libmedia"], } cc_library_static { name: "libstagefright_timedtext2", srcs: ["TextDescriptions2.cpp"], static_libs: [ "libmediaplayer2-protos", "libprotobuf-cpp-lite", ], cflags: [ "-Wno-multichar", "-Werror", "-Wall", ], sanitize: { misc_undefined: [ "signed-integer-overflow", ], cfi: true, diag: { cfi: true, }, }, include_dirs: [ "frameworks/av/media/libstagefright", ], shared_libs: ["libmedia"], } media/libstagefright/timedtext/TextDescriptions2.cpp 0 → 100644 +188 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "TextDescriptions2.h" #include <media/stagefright/foundation/ByteUtils.h> #include <media/stagefright/MediaErrors.h> namespace android { TextDescriptions2::TextDescriptions2() { } status_t TextDescriptions2::getPlayerMessageOfDescriptions( const uint8_t *data, ssize_t size, uint32_t flags, int timeMs, PlayerMessage *playerMsg) { if (flags & IN_BAND_TEXT_3GPP) { if (flags & GLOBAL_DESCRIPTIONS) { return extract3GPPGlobalDescriptions(data, size, playerMsg); } else if (flags & LOCAL_DESCRIPTIONS) { return extract3GPPLocalDescriptions(data, size, timeMs, playerMsg); } } else if (flags & OUT_OF_BAND_TEXT_SRT) { if (flags & LOCAL_DESCRIPTIONS) { return extractSRTLocalDescriptions(data, size, timeMs, playerMsg); } } return ERROR_UNSUPPORTED; } // Parse the SRT text sample, and store the timing and text sample in a PlayerMessage. // The PlayerMessage will be sent to MediaPlayer2.java through event, and will be // parsed in TimedText.java. status_t TextDescriptions2::extractSRTLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg) { playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING); playerMsg->add_values()->set_int32_value(KEY_START_TIME); playerMsg->add_values()->set_int32_value(timeMs); playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT); playerMsg->add_values()->set_bytes_value(data, size); return OK; } // Extract the local 3GPP display descriptions. 3GPP local descriptions // are appended to the text sample if any. status_t TextDescriptions2::extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg) { playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING); // write start time to display this text sample playerMsg->add_values()->set_int32_value(KEY_START_TIME); playerMsg->add_values()->set_int32_value(timeMs); if (size < 2) { return OK; } ssize_t textLen = (*data) << 8 | (*(data + 1)); if (size < textLen + 2) { return OK; } // write text sample length and text sample itself playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT); playerMsg->add_values()->set_bytes_value(data + 2, textLen); if (size > textLen + 2) { data += (textLen + 2); size -= (textLen + 2); } else { return OK; } while (size >= 8) { const uint8_t *tmpData = data; ssize_t chunkSize = U32_AT(tmpData); // size includes size and type uint32_t chunkType = U32_AT(tmpData + 4); if (chunkSize <= 8 || chunkSize > size) { return OK; } size_t remaining = chunkSize - 8; tmpData += 8; switch(chunkType) { // 'tbox' box to indicate the position of the text with values // of top, left, bottom and right case FOURCC('t', 'b', 'o', 'x'): { if (remaining < 8) { return OK; } playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS); playerMsg->add_values()->set_int32_value(U16_AT(tmpData)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6)); tmpData += 8; remaining -= 8; break; } default: { break; } } data += chunkSize; size -= chunkSize; } return OK; } // To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a PlayerMessage status_t TextDescriptions2::extract3GPPGlobalDescriptions( const uint8_t *data, ssize_t size, PlayerMessage *playerMsg) { playerMsg->add_values()->set_int32_value(KEY_GLOBAL_SETTING); while (size >= 8) { ssize_t chunkSize = U32_AT(data); uint32_t chunkType = U32_AT(data + 4); const uint8_t *tmpData = data; tmpData += 8; size_t remaining = size - 8; if (size < chunkSize) { return OK; } switch(chunkType) { case FOURCC('t', 'x', '3', 'g'): { if (remaining < 18) { return OK; } // Skip DISPLAY_FLAGS, STRUCT_JUSTIFICATION, and BACKGROUND_COLOR_RGBA tmpData += 18; remaining -= 18; if (remaining < 8) { return OK; } playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS); playerMsg->add_values()->set_int32_value(U16_AT(tmpData)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6)); tmpData += 8; remaining -= 18; // Ignore remaining data. break; } default: { break; } } data += chunkSize; size -= chunkSize; } return OK; } } // namespace android media/libstagefright/timedtext/TextDescriptions2.h 0 → 100644 +88 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TEXT_DESCRIPTIONS2_H_ #define TEXT_DESCRIPTIONS2_H_ #include <binder/Parcel.h> #include <media/stagefright/foundation/ABase.h> #include "mediaplayer2.pb.h" using android::media::MediaPlayer2Proto::PlayerMessage; namespace android { class TextDescriptions2 { public: enum { IN_BAND_TEXT_3GPP = 0x01, OUT_OF_BAND_TEXT_SRT = 0x02, GLOBAL_DESCRIPTIONS = 0x100, LOCAL_DESCRIPTIONS = 0x200, }; static status_t getPlayerMessageOfDescriptions( const uint8_t *data, ssize_t size, uint32_t flags, int timeMs, PlayerMessage *playerMsg); private: TextDescriptions2(); enum { // These keys must be in sync with the keys in TimedText.java KEY_DISPLAY_FLAGS = 1, // int KEY_STYLE_FLAGS = 2, // int KEY_BACKGROUND_COLOR_RGBA = 3, // int KEY_HIGHLIGHT_COLOR_RGBA = 4, // int KEY_SCROLL_DELAY = 5, // int KEY_WRAP_TEXT = 6, // int KEY_START_TIME = 7, // int KEY_STRUCT_BLINKING_TEXT_LIST = 8, // List<CharPos> KEY_STRUCT_FONT_LIST = 9, // List<Font> KEY_STRUCT_HIGHLIGHT_LIST = 10, // List<CharPos> KEY_STRUCT_HYPER_TEXT_LIST = 11, // List<HyperText> KEY_STRUCT_KARAOKE_LIST = 12, // List<Karaoke> KEY_STRUCT_STYLE_LIST = 13, // List<Style> KEY_STRUCT_TEXT_POS = 14, // TextPos KEY_STRUCT_JUSTIFICATION = 15, // Justification KEY_STRUCT_TEXT = 16, // Text KEY_GLOBAL_SETTING = 101, KEY_LOCAL_SETTING = 102, KEY_START_CHAR = 103, KEY_END_CHAR = 104, KEY_FONT_ID = 105, KEY_FONT_SIZE = 106, KEY_TEXT_COLOR_RGBA = 107, }; static status_t extractSRTLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg); static status_t extract3GPPGlobalDescriptions( const uint8_t *data, ssize_t size, PlayerMessage *playerMsg); static status_t extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg); DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions2); }; } // namespace android #endif // TEXT_DESCRIPTIONS2_H_ Loading
media/libmediaplayer2/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ cc_library { "libprotobuf-cpp-lite", "libstagefright_nuplayer2", "libstagefright_rtsp", "libstagefright_timedtext", "libstagefright_timedtext2", ], export_include_dirs: [ Loading
media/libmediaplayer2/nuplayer2/NuPlayer2.cpp +9 −10 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ #include "NuPlayer2Source.h" #include "RTSPSource2.h" #include "GenericSource2.h" #include "TextDescriptions.h" #include "TextDescriptions2.h" #include "ATSParser.h" Loading Loading @@ -2870,7 +2870,7 @@ void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) { const void *data; size_t size = 0; int64_t timeUs; int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP; int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP; AString mime; CHECK(buffer->meta()->findString("mime", &mime)); Loading @@ -2879,22 +2879,21 @@ void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) { data = buffer->data(); size = buffer->size(); Parcel parcel; PlayerMessage playerMsg; if (size > 0) { CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); int32_t global = 0; if (buffer->meta()->findInt32("global", &global) && global) { flag |= TextDescriptions::GLOBAL_DESCRIPTIONS; flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS; } else { flag |= TextDescriptions::LOCAL_DESCRIPTIONS; flag |= TextDescriptions2::LOCAL_DESCRIPTIONS; } TextDescriptions::getParcelOfDescriptions( (const uint8_t *)data, size, flag, timeUs / 1000, &parcel); TextDescriptions2::getPlayerMessageOfDescriptions( (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg); } if ((parcel.dataSize() > 0)) { // TODO: convert text data to PlayerMessage // notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &parcel); if (playerMsg.values_size() > 0) { notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg); } else { // send an empty timed text notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0); } Loading
media/libstagefright/timedtext/Android.bp +33 −0 Original line number Diff line number Diff line Loading @@ -25,3 +25,36 @@ cc_library_static { shared_libs: ["libmedia"], } cc_library_static { name: "libstagefright_timedtext2", srcs: ["TextDescriptions2.cpp"], static_libs: [ "libmediaplayer2-protos", "libprotobuf-cpp-lite", ], cflags: [ "-Wno-multichar", "-Werror", "-Wall", ], sanitize: { misc_undefined: [ "signed-integer-overflow", ], cfi: true, diag: { cfi: true, }, }, include_dirs: [ "frameworks/av/media/libstagefright", ], shared_libs: ["libmedia"], }
media/libstagefright/timedtext/TextDescriptions2.cpp 0 → 100644 +188 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "TextDescriptions2.h" #include <media/stagefright/foundation/ByteUtils.h> #include <media/stagefright/MediaErrors.h> namespace android { TextDescriptions2::TextDescriptions2() { } status_t TextDescriptions2::getPlayerMessageOfDescriptions( const uint8_t *data, ssize_t size, uint32_t flags, int timeMs, PlayerMessage *playerMsg) { if (flags & IN_BAND_TEXT_3GPP) { if (flags & GLOBAL_DESCRIPTIONS) { return extract3GPPGlobalDescriptions(data, size, playerMsg); } else if (flags & LOCAL_DESCRIPTIONS) { return extract3GPPLocalDescriptions(data, size, timeMs, playerMsg); } } else if (flags & OUT_OF_BAND_TEXT_SRT) { if (flags & LOCAL_DESCRIPTIONS) { return extractSRTLocalDescriptions(data, size, timeMs, playerMsg); } } return ERROR_UNSUPPORTED; } // Parse the SRT text sample, and store the timing and text sample in a PlayerMessage. // The PlayerMessage will be sent to MediaPlayer2.java through event, and will be // parsed in TimedText.java. status_t TextDescriptions2::extractSRTLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg) { playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING); playerMsg->add_values()->set_int32_value(KEY_START_TIME); playerMsg->add_values()->set_int32_value(timeMs); playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT); playerMsg->add_values()->set_bytes_value(data, size); return OK; } // Extract the local 3GPP display descriptions. 3GPP local descriptions // are appended to the text sample if any. status_t TextDescriptions2::extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg) { playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING); // write start time to display this text sample playerMsg->add_values()->set_int32_value(KEY_START_TIME); playerMsg->add_values()->set_int32_value(timeMs); if (size < 2) { return OK; } ssize_t textLen = (*data) << 8 | (*(data + 1)); if (size < textLen + 2) { return OK; } // write text sample length and text sample itself playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT); playerMsg->add_values()->set_bytes_value(data + 2, textLen); if (size > textLen + 2) { data += (textLen + 2); size -= (textLen + 2); } else { return OK; } while (size >= 8) { const uint8_t *tmpData = data; ssize_t chunkSize = U32_AT(tmpData); // size includes size and type uint32_t chunkType = U32_AT(tmpData + 4); if (chunkSize <= 8 || chunkSize > size) { return OK; } size_t remaining = chunkSize - 8; tmpData += 8; switch(chunkType) { // 'tbox' box to indicate the position of the text with values // of top, left, bottom and right case FOURCC('t', 'b', 'o', 'x'): { if (remaining < 8) { return OK; } playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS); playerMsg->add_values()->set_int32_value(U16_AT(tmpData)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6)); tmpData += 8; remaining -= 8; break; } default: { break; } } data += chunkSize; size -= chunkSize; } return OK; } // To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a PlayerMessage status_t TextDescriptions2::extract3GPPGlobalDescriptions( const uint8_t *data, ssize_t size, PlayerMessage *playerMsg) { playerMsg->add_values()->set_int32_value(KEY_GLOBAL_SETTING); while (size >= 8) { ssize_t chunkSize = U32_AT(data); uint32_t chunkType = U32_AT(data + 4); const uint8_t *tmpData = data; tmpData += 8; size_t remaining = size - 8; if (size < chunkSize) { return OK; } switch(chunkType) { case FOURCC('t', 'x', '3', 'g'): { if (remaining < 18) { return OK; } // Skip DISPLAY_FLAGS, STRUCT_JUSTIFICATION, and BACKGROUND_COLOR_RGBA tmpData += 18; remaining -= 18; if (remaining < 8) { return OK; } playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS); playerMsg->add_values()->set_int32_value(U16_AT(tmpData)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4)); playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6)); tmpData += 8; remaining -= 18; // Ignore remaining data. break; } default: { break; } } data += chunkSize; size -= chunkSize; } return OK; } } // namespace android
media/libstagefright/timedtext/TextDescriptions2.h 0 → 100644 +88 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TEXT_DESCRIPTIONS2_H_ #define TEXT_DESCRIPTIONS2_H_ #include <binder/Parcel.h> #include <media/stagefright/foundation/ABase.h> #include "mediaplayer2.pb.h" using android::media::MediaPlayer2Proto::PlayerMessage; namespace android { class TextDescriptions2 { public: enum { IN_BAND_TEXT_3GPP = 0x01, OUT_OF_BAND_TEXT_SRT = 0x02, GLOBAL_DESCRIPTIONS = 0x100, LOCAL_DESCRIPTIONS = 0x200, }; static status_t getPlayerMessageOfDescriptions( const uint8_t *data, ssize_t size, uint32_t flags, int timeMs, PlayerMessage *playerMsg); private: TextDescriptions2(); enum { // These keys must be in sync with the keys in TimedText.java KEY_DISPLAY_FLAGS = 1, // int KEY_STYLE_FLAGS = 2, // int KEY_BACKGROUND_COLOR_RGBA = 3, // int KEY_HIGHLIGHT_COLOR_RGBA = 4, // int KEY_SCROLL_DELAY = 5, // int KEY_WRAP_TEXT = 6, // int KEY_START_TIME = 7, // int KEY_STRUCT_BLINKING_TEXT_LIST = 8, // List<CharPos> KEY_STRUCT_FONT_LIST = 9, // List<Font> KEY_STRUCT_HIGHLIGHT_LIST = 10, // List<CharPos> KEY_STRUCT_HYPER_TEXT_LIST = 11, // List<HyperText> KEY_STRUCT_KARAOKE_LIST = 12, // List<Karaoke> KEY_STRUCT_STYLE_LIST = 13, // List<Style> KEY_STRUCT_TEXT_POS = 14, // TextPos KEY_STRUCT_JUSTIFICATION = 15, // Justification KEY_STRUCT_TEXT = 16, // Text KEY_GLOBAL_SETTING = 101, KEY_LOCAL_SETTING = 102, KEY_START_CHAR = 103, KEY_END_CHAR = 104, KEY_FONT_ID = 105, KEY_FONT_SIZE = 106, KEY_TEXT_COLOR_RGBA = 107, }; static status_t extractSRTLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg); static status_t extract3GPPGlobalDescriptions( const uint8_t *data, ssize_t size, PlayerMessage *playerMsg); static status_t extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg); DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions2); }; } // namespace android #endif // TEXT_DESCRIPTIONS2_H_