| 909 | } |
| 910 | |
| 911 | virtual void Decode (GMPVideoEncodedFrame* inputFrame, |
| 912 | bool missingFrames, |
| 913 | const uint8_t* aCodecSpecificInfo, |
| 914 | uint32_t aCodecSpecificInfoLength, |
| 915 | int64_t renderTimeMs = -1) { |
| 916 | GMPLOG (GL_DEBUG, __FUNCTION__ |
| 917 | << "Decoding frame size=" << inputFrame->Size() |
| 918 | << " timestamp=" << inputFrame->TimeStamp()); |
| 919 | stats_.FrameIn(); |
| 920 | //const GMPCodecSpecificInfo *codecSpecificInfo = (GMPCodecSpecificInfo) aCodecSpecificInfo; |
| 921 | |
| 922 | // Convert to H.264 start codes |
| 923 | switch (inputFrame->BufferType()) { |
| 924 | case GMP_BufferSingle: |
| 925 | case GMP_BufferLength8: |
| 926 | case GMP_BufferLength16: |
| 927 | case GMP_BufferLength24: |
| 928 | // We should look to support these, especially GMP_BufferSingle |
| 929 | assert (false); |
| 930 | break; |
| 931 | |
| 932 | case GMP_BufferLength32: { |
| 933 | uint8_t* start_code = inputFrame->Buffer(); |
| 934 | // start code should be at least four bytes from the end or we risk |
| 935 | // reading/writing outside the buffer. |
| 936 | while (start_code < inputFrame->Buffer() + inputFrame->Size() - 4) { |
| 937 | static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 }; |
| 938 | uint8_t* lenp = start_code; |
| 939 | start_code += * (reinterpret_cast<int32_t*> (lenp)); |
| 940 | memcpy (lenp, code, 4); |
| 941 | } |
| 942 | } |
| 943 | break; |
| 944 | |
| 945 | default: |
| 946 | assert (false); |
| 947 | break; |
| 948 | } |
| 949 | DECODING_STATE dState = dsErrorFree; |
| 950 | worker_thread_->Post (WrapTaskRefCounted ( |
| 951 | this, &OpenH264VideoDecoder::Decode_w, |
| 952 | inputFrame, |
| 953 | missingFrames, |
| 954 | dState, |
| 955 | renderTimeMs)); |
| 956 | if (dState) { |
| 957 | Error (GMPGenericErr); |
| 958 | } |
| 959 | } |
| 960 | |
| 961 | virtual void Reset() { |
| 962 | if (gmp_api_version_ >= kGMPVersion34) { |
nothing calls this directly
no test coverage detected