Esempio n. 1
0
        /* protected override int writeFrame( EncodedBuffer destBuffer, int cb )
         * {
         *      // Read the complete sample
         *      Span<byte> dest = destBuffer.span;
         *      stream.Read( dest.Slice( 0, cb ) );
         *
         *      // Produce NALU start codes.
         *      for( int offset = 0; offset < cb; )
         *      {
         *              int naluLength = ( dest[ offset ] << 16 ) | ( dest[ offset + 1 ] << 8 ) | dest[ offset + 2 ];
         *
         *              dest[ offset ] = 0;
         *              dest[ offset + 1 ] = 0;
         *              dest[ offset + 2 ] = 1;
         *
         *              offset += ( naluLength + 3 );
         *      }
         *      return cb;
         * } */

        protected override int writeNalu(EncodedBuffer destBuffer, out eNaluAction result, out eNaluType type)
        {
            Span <byte> naluLength = stackalloc byte[4];

            naluLength[0] = 0;
            stream.read(naluLength.Slice(1));
            int cbNalu = BitConverter.ToInt32(naluLength).endian();

            Span <byte> dest = destBuffer.span;

            // Write NALU start code to mapped memory
            EmulationPrevention.writeStartCode4(dest, 0);
            // Read NALU payload from file into mapped memory
            Span <byte> naluPayload = dest.Slice(4, cbNalu);

            stream.read(naluPayload);
            destBuffer.setLength(cbNalu + 4);
            type = setBufferMetadata(destBuffer, naluPayload, out result);
            return(cbNalu + 3);
        }
Esempio n. 2
0
        eNaluAction iVideoTrackReader.writeNextNalu(EncodedBuffer dest)
        {
            if (EOF)
            {
                return(eNaluAction.EOF);
            }

            int         naluLength;
            Span <byte> naluPayload;

            lock (clusters.syncRoot)
            {
                // Seek to the blob
                seek(ref readerState);

                // Read 4-bytes NALU length. Unlike mpeg4, MKV header never says it's 4 bytes, i.e. just guessing here.
                Span <byte> naluLengthSpan = stackalloc byte[4];
                read(ref readerState, naluLengthSpan);
                naluLength = BinaryPrimitives.ReadInt32BigEndian(naluLengthSpan);
                Debug.Assert(readerState.bytesLeft >= naluLength);

                // Write NALU start code to mapped memory
                EmulationPrevention.writeStartCode4(dest.span, 0);

                // Write the payload
                naluPayload = dest.span.Slice(4, naluLength);
                read(ref readerState, naluPayload);
            }

            dest.setLength(naluLength + 4);

            // Parse the payload. The shared memory mapped by the driver is both readable and writeable.
            eNaluAction act = setBufferMetadata(dest, naluPayload);

            if (readerState.bytesLeft <= 0)
            {
                advance();
            }
            return(act);
        }
Esempio n. 3
0
        protected eNaluType setBufferMetadata(EncodedBuffer destBuffer, ReadOnlySpan <byte> data, out eNaluAction result)
        {
            // NALU header
            eNaluType naluType = (eNaluType)(data[0] & 0x1f);
            BitReader reader   = new BitReader(data);

            reader.skipBits(8);

            switch (naluType)
            {
            case eNaluType.IDR:
            case eNaluType.NonIDR:
            {
                uint first_mb_in_slice = reader.unsignedGolomb();                                   // address of the first macroblock in the slice
                uint slice_type        = reader.unsignedGolomb();
                if (slice_type > 9)
                {
                    throw new ArgumentException("Malformed h264 stream, slice_type must be in [ 0 .. 9 ] interval");
                }
                destBuffer.setSliceTypeFlag(slice_type);

                uint pic_parameter_set_id = reader.unsignedGolomb();
                if (separateColourPlaneFlag)
                {
                    reader.skipBits(2);                                         // uint colour_plane_id
                }
                int frameIndex = reader.readInt(frameIndexBits);
                // Logger.logVerbose( "{0} NALU: slice type {1}, frame index {2}", naluType, (eSliceType)slice_type, frameIndex );
                // if( naluType != eNaluType.NonIDR )
                //	Logger.logVerbose( "{0} NALU: slice type {1}, frame index {2}", naluType, (eSliceType)slice_type, frameIndex );
            }
                destBuffer.setTimestamp(sampleReader.timestamp);
                result = eNaluAction.Decode;
                return(naluType);

            case eNaluType.SEI:
            {
                sSeiMessage sei = new sSeiMessage(ref reader, ref timingFormat);
                if (sei.type == eSeiType.PicTiming)
                {
                    // ISO/IEC 14496-15 section 5.2.2:
                    // All timing information is external to stream.
                    // Timing provided within the AVC stream in this file format should be ignored as it may contradict the timing provided by the file format and may not be correct or consistent within itself.
                    result = eNaluAction.Ignore;
                }
                else
                {
                    // Logger.logVerbose( "{0} NALU: {1}", naluType, sei );
                    // destBuffer.setTimestamp( sampleReader.timestamp );
                    result = eNaluAction.Decode;
                }
                return(naluType);
            }

            default:
                // Logger.logVerbose( "{0} NALU", naluType );
                // destBuffer.setTimestamp( sampleReader.timestamp );
                result = eNaluAction.Decode;
                return(naluType);
            }
        }
Esempio n. 4
0
        /// <summary>Write complete sample to the buffer.</summary>
        /// <remarks>This requires <see cref="Linux.eImageFormatDescriptionFlags.ContinuousByteStream" /> capability flag for the h264 format.
        /// Needless to say, Pi4 hardware decoder ain’t supporting that flag.</remarks>
        // protected abstract int writeFrame( EncodedBuffer dest, int cb );

        /// <summary>Write a single NALU to the buffer, including start code. Returns count of bytes read from the file.</summary>
        protected abstract int writeNalu(EncodedBuffer dest, out eNaluAction result, out eNaluType type);