OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 TRACE_EVENT_ASYNC_STEP_INTO1("media", "SourceBuffer::appendBuffer", this, "a
ppending", "appendSize", static_cast<unsigned>(appendSize)); | 809 TRACE_EVENT_ASYNC_STEP_INTO1("media", "SourceBuffer::appendBuffer", this, "a
ppending", "appendSize", static_cast<unsigned>(appendSize)); |
810 | 810 |
811 // |zero| is used for 0 byte appends so we always have a valid pointer. | 811 // |zero| is used for 0 byte appends so we always have a valid pointer. |
812 // We need to convey all appends, even 0 byte ones to |m_webSourceBuffer| | 812 // We need to convey all appends, even 0 byte ones to |m_webSourceBuffer| |
813 // so that it can clear its end of stream state if necessary. | 813 // so that it can clear its end of stream state if necessary. |
814 unsigned char zero = 0; | 814 unsigned char zero = 0; |
815 unsigned char* appendData = &zero; | 815 unsigned char* appendData = &zero; |
816 if (appendSize) | 816 if (appendSize) |
817 appendData = m_pendingAppendData.data() + m_pendingAppendDataOffset; | 817 appendData = m_pendingAppendData.data() + m_pendingAppendDataOffset; |
818 | 818 |
819 m_webSourceBuffer->append(appendData, appendSize, &m_timestampOffset); | 819 bool appendSuccess = m_webSourceBuffer->append(appendData, appendSize, &m_ti
mestampOffset); |
820 | 820 |
821 m_pendingAppendDataOffset += appendSize; | 821 if (!appendSuccess) { |
| 822 m_pendingAppendData.clear(); |
| 823 m_pendingAppendDataOffset = 0; |
| 824 appendError(DecodeError); |
| 825 } else { |
| 826 m_pendingAppendDataOffset += appendSize; |
822 | 827 |
823 if (m_pendingAppendDataOffset < m_pendingAppendData.size()) { | 828 if (m_pendingAppendDataOffset < m_pendingAppendData.size()) { |
824 m_appendBufferAsyncPartRunner->runAsync(); | 829 m_appendBufferAsyncPartRunner->runAsync(); |
825 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this
, "nextPieceDelay"); | 830 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer",
this, "nextPieceDelay"); |
826 return; | 831 return; |
| 832 } |
| 833 |
| 834 // 3. Set the updating attribute to false. |
| 835 m_updating = false; |
| 836 m_pendingAppendData.clear(); |
| 837 m_pendingAppendDataOffset = 0; |
| 838 |
| 839 // 4. Queue a task to fire a simple event named update at this SourceBuf
fer object. |
| 840 scheduleEvent(EventTypeNames::update); |
| 841 |
| 842 // 5. Queue a task to fire a simple event named updateend at this Source
Buffer object. |
| 843 scheduleEvent(EventTypeNames::updateend); |
827 } | 844 } |
828 | 845 |
829 // 3. Set the updating attribute to false. | |
830 m_updating = false; | |
831 m_pendingAppendData.clear(); | |
832 m_pendingAppendDataOffset = 0; | |
833 | |
834 // 4. Queue a task to fire a simple event named update at this SourceBuffer
object. | |
835 scheduleEvent(EventTypeNames::update); | |
836 | |
837 // 5. Queue a task to fire a simple event named updateend at this SourceBuff
er object. | |
838 scheduleEvent(EventTypeNames::updateend); | |
839 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); | 846 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); |
840 SBLOG << __FUNCTION__ << " done. this=" << this << " buffered=" << webTimeRa
ngesToString(m_webSourceBuffer->buffered()); | 847 SBLOG << __FUNCTION__ << " done. this=" << this << " buffered=" << webTimeRa
ngesToString(m_webSourceBuffer->buffered()); |
841 } | 848 } |
842 | 849 |
843 void SourceBuffer::removeAsyncPart() | 850 void SourceBuffer::removeAsyncPart() |
844 { | 851 { |
845 DCHECK(m_updating); | 852 DCHECK(m_updating); |
846 DCHECK_GE(m_pendingRemoveStart, 0); | 853 DCHECK_GE(m_pendingRemoveStart, 0); |
847 DCHECK_LT(m_pendingRemoveStart, m_pendingRemoveEnd); | 854 DCHECK_LT(m_pendingRemoveStart, m_pendingRemoveEnd); |
848 | 855 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 DCHECK(m_loader); | 910 DCHECK(m_loader); |
904 DCHECK(m_stream); | 911 DCHECK(m_stream); |
905 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendStream", this, "a
ppendStreamAsyncPart"); | 912 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendStream", this, "a
ppendStreamAsyncPart"); |
906 | 913 |
907 // Section 3.5.6 Stream Append Loop | 914 // Section 3.5.6 Stream Append Loop |
908 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop | 915 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop |
909 | 916 |
910 // 1. If maxSize is set, then let bytesLeft equal maxSize. | 917 // 1. If maxSize is set, then let bytesLeft equal maxSize. |
911 // 2. Loop Top: If maxSize is set and bytesLeft equals 0, then jump to the l
oop done step below. | 918 // 2. Loop Top: If maxSize is set and bytesLeft equals 0, then jump to the l
oop done step below. |
912 if (m_streamMaxSizeValid && !m_streamMaxSize) { | 919 if (m_streamMaxSizeValid && !m_streamMaxSize) { |
913 appendStreamDone(true); | 920 appendStreamDone(NoError); |
914 return; | 921 return; |
915 } | 922 } |
916 | 923 |
917 // Steps 3-11 are handled by m_loader. | 924 // Steps 3-11 are handled by m_loader. |
918 // Note: Passing 0 here signals that maxSize was not set. (i.e. Read all the
data in the stream). | 925 // Note: Passing 0 here signals that maxSize was not set. (i.e. Read all the
data in the stream). |
919 m_loader->start(getExecutionContext(), *m_stream, m_streamMaxSizeValid ? m_s
treamMaxSize : 0); | 926 m_loader->start(getExecutionContext(), *m_stream, m_streamMaxSizeValid ? m_s
treamMaxSize : 0); |
920 } | 927 } |
921 | 928 |
922 void SourceBuffer::appendStreamDone(bool success) | 929 void SourceBuffer::appendStreamDone(AppendStreamDoneAction action) |
923 { | 930 { |
924 DCHECK(m_updating); | 931 DCHECK(m_updating); |
925 DCHECK(m_loader); | 932 DCHECK(m_loader); |
926 DCHECK(m_stream); | 933 DCHECK(m_stream); |
927 | 934 |
928 clearAppendStreamState(); | 935 clearAppendStreamState(); |
929 | 936 |
930 if (!success) { | 937 if (action != NoError) { |
931 appendError(false); | 938 if (action == RunAppendErrorWithNoDecodeError) { |
| 939 appendError(NoDecodeError); |
| 940 } else { |
| 941 DCHECK_EQ(action, RunAppendErrorWithDecodeError); |
| 942 appendError(DecodeError); |
| 943 } |
| 944 |
932 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); | 945 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); |
933 return; | 946 return; |
934 } | 947 } |
935 | 948 |
936 // Section 3.5.6 Stream Append Loop | 949 // Section 3.5.6 Stream Append Loop |
937 // Steps 1-11 are handled by appendStreamAsyncPart(), |m_loader|, and |m_web
SourceBuffer|. | 950 // Steps 1-11 are handled by appendStreamAsyncPart(), |m_loader|, and |m_web
SourceBuffer|. |
938 | 951 |
939 // 12. Loop Done: Set the updating attribute to false. | 952 // 12. Loop Done: Set the updating attribute to false. |
940 m_updating = false; | 953 m_updating = false; |
941 | 954 |
942 // 13. Queue a task to fire a simple event named update at this SourceBuffer
object. | 955 // 13. Queue a task to fire a simple event named update at this SourceBuffer
object. |
943 scheduleEvent(EventTypeNames::update); | 956 scheduleEvent(EventTypeNames::update); |
944 | 957 |
945 // 14. Queue a task to fire a simple event named updateend at this SourceBuf
fer object. | 958 // 14. Queue a task to fire a simple event named updateend at this SourceBuf
fer object. |
946 scheduleEvent(EventTypeNames::updateend); | 959 scheduleEvent(EventTypeNames::updateend); |
947 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); | 960 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); |
948 SBLOG << __FUNCTION__ << " ended. this=" << this << " buffered=" << webTimeR
angesToString(m_webSourceBuffer->buffered()); | 961 SBLOG << __FUNCTION__ << " ended. this=" << this << " buffered=" << webTimeR
angesToString(m_webSourceBuffer->buffered()); |
949 } | 962 } |
950 | 963 |
951 void SourceBuffer::clearAppendStreamState() | 964 void SourceBuffer::clearAppendStreamState() |
952 { | 965 { |
953 m_streamMaxSizeValid = false; | 966 m_streamMaxSizeValid = false; |
954 m_streamMaxSize = 0; | 967 m_streamMaxSize = 0; |
955 m_loader.reset(); | 968 m_loader.reset(); |
956 m_stream = nullptr; | 969 m_stream = nullptr; |
957 } | 970 } |
958 | 971 |
959 void SourceBuffer::appendError(bool decodeError) | 972 void SourceBuffer::appendError(AppendError err) |
960 { | 973 { |
961 SBLOG << __FUNCTION__ << " this=" << this << " decodeError=" << decodeError; | 974 SBLOG << __FUNCTION__ << " this=" << this << " AppendError=" << err; |
962 // Section 3.5.3 Append Error Algorithm | 975 // Section 3.5.3 Append Error Algorithm |
963 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou
rce.html#sourcebuffer-append-error | 976 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou
rce.html#sourcebuffer-append-error |
964 | 977 |
965 // 1. Run the reset parser state algorithm. | 978 // 1. Run the reset parser state algorithm. |
966 m_webSourceBuffer->resetParserState(); | 979 m_webSourceBuffer->resetParserState(); |
967 | 980 |
968 // 2. Set the updating attribute to false. | 981 // 2. Set the updating attribute to false. |
969 m_updating = false; | 982 m_updating = false; |
970 | 983 |
971 // 3. Queue a task to fire a simple event named error at this SourceBuffer o
bject. | 984 // 3. Queue a task to fire a simple event named error at this SourceBuffer o
bject. |
972 scheduleEvent(EventTypeNames::error); | 985 scheduleEvent(EventTypeNames::error); |
973 | 986 |
974 // 4. Queue a task to fire a simple event named updateend at this SourceBuff
er object. | 987 // 4. Queue a task to fire a simple event named updateend at this SourceBuff
er object. |
975 scheduleEvent(EventTypeNames::updateend); | 988 scheduleEvent(EventTypeNames::updateend); |
976 | 989 |
977 // 5. If decode error is true, then run the end of stream algorithm with the | 990 // 5. If decode error is true, then run the end of stream algorithm with the |
978 // error parameter set to "decode". | 991 // error parameter set to "decode". |
979 if (decodeError) | 992 if (err == DecodeError) { |
980 m_source->endOfStream("decode", ASSERT_NO_EXCEPTION); | 993 m_source->endOfStream("decode", ASSERT_NO_EXCEPTION); |
| 994 } else { |
| 995 DCHECK_EQ(err, NoDecodeError); |
| 996 // Nothing else to do in this case. |
| 997 } |
981 } | 998 } |
982 | 999 |
983 void SourceBuffer::didStartLoading() | 1000 void SourceBuffer::didStartLoading() |
984 { | 1001 { |
985 SBLOG << __FUNCTION__ << " this=" << this; | 1002 SBLOG << __FUNCTION__ << " this=" << this; |
986 } | 1003 } |
987 | 1004 |
988 void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength
) | 1005 void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength
) |
989 { | 1006 { |
990 SBLOG << __FUNCTION__ << " this=" << this << " dataLength=" << dataLength; | 1007 SBLOG << __FUNCTION__ << " this=" << this << " dataLength=" << dataLength; |
991 DCHECK(m_updating); | 1008 DCHECK(m_updating); |
992 DCHECK(m_loader); | 1009 DCHECK(m_loader); |
993 | 1010 |
994 // Section 3.5.6 Stream Append Loop | 1011 // Section 3.5.6 Stream Append Loop |
995 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop | 1012 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop |
996 | 1013 |
997 // 10. Run the coded frame eviction algorithm. | 1014 // 10. Run the coded frame eviction algorithm. |
998 if (!evictCodedFrames(dataLength)) { | 1015 if (!evictCodedFrames(dataLength)) { |
999 // 11. (in appendStreamDone) If the buffer full flag equals true, then r
un the append error algorithm with the decode error parameter set to false and a
bort this algorithm. | 1016 // 11. (in appendStreamDone) If the buffer full flag equals true, then r
un the append error algorithm with the decode error parameter set to false and a
bort this algorithm. |
1000 appendStreamDone(false); | 1017 appendStreamDone(RunAppendErrorWithNoDecodeError); |
1001 return; | 1018 return; |
1002 } | 1019 } |
1003 | 1020 |
1004 m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), data
Length, &m_timestampOffset); | 1021 if (!m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data),
dataLength, &m_timestampOffset)) |
| 1022 appendStreamDone(RunAppendErrorWithDecodeError); |
1005 } | 1023 } |
1006 | 1024 |
1007 void SourceBuffer::didFinishLoading() | 1025 void SourceBuffer::didFinishLoading() |
1008 { | 1026 { |
1009 SBLOG << __FUNCTION__ << " this=" << this; | 1027 SBLOG << __FUNCTION__ << " this=" << this; |
1010 DCHECK(m_loader); | 1028 DCHECK(m_loader); |
1011 appendStreamDone(true); | 1029 appendStreamDone(NoError); |
1012 } | 1030 } |
1013 | 1031 |
1014 void SourceBuffer::didFail(FileError::ErrorCode errorCode) | 1032 void SourceBuffer::didFail(FileError::ErrorCode errorCode) |
1015 { | 1033 { |
1016 SBLOG << __FUNCTION__ << " this=" << this << " errorCode=" << errorCode; | 1034 SBLOG << __FUNCTION__ << " this=" << this << " errorCode=" << errorCode; |
1017 // m_loader might be already released, in case appendStream has failed due | 1035 // m_loader might be already released, in case appendStream has failed due |
1018 // to evictCodedFrames failing in didReceiveDataForClient. In that case | 1036 // to evictCodedFrames or WebSourceBuffer append failing in |
1019 // appendStreamDone will be invoked from there, no need to repeat it here. | 1037 // didReceiveDataForClient. In that case appendStreamDone will be invoked |
| 1038 // from there, no need to repeat it here. |
1020 if (m_loader) | 1039 if (m_loader) |
1021 appendStreamDone(false); | 1040 appendStreamDone(RunAppendErrorWithNoDecodeError); |
1022 } | 1041 } |
1023 | 1042 |
1024 DEFINE_TRACE(SourceBuffer) | 1043 DEFINE_TRACE(SourceBuffer) |
1025 { | 1044 { |
1026 visitor->trace(m_source); | 1045 visitor->trace(m_source); |
1027 visitor->trace(m_trackDefaults); | 1046 visitor->trace(m_trackDefaults); |
1028 visitor->trace(m_asyncEventQueue); | 1047 visitor->trace(m_asyncEventQueue); |
1029 visitor->trace(m_appendBufferAsyncPartRunner); | 1048 visitor->trace(m_appendBufferAsyncPartRunner); |
1030 visitor->trace(m_removeAsyncPartRunner); | 1049 visitor->trace(m_removeAsyncPartRunner); |
1031 visitor->trace(m_appendStreamAsyncPartRunner); | 1050 visitor->trace(m_appendStreamAsyncPartRunner); |
1032 visitor->trace(m_stream); | 1051 visitor->trace(m_stream); |
1033 visitor->trace(m_audioTracks); | 1052 visitor->trace(m_audioTracks); |
1034 visitor->trace(m_videoTracks); | 1053 visitor->trace(m_videoTracks); |
1035 EventTargetWithInlineData::trace(visitor); | 1054 EventTargetWithInlineData::trace(visitor); |
1036 ActiveDOMObject::trace(visitor); | 1055 ActiveDOMObject::trace(visitor); |
1037 } | 1056 } |
1038 | 1057 |
1039 } // namespace blink | 1058 } // namespace blink |
OLD | NEW |