示例#1
0
        static uint h264e_bs_byte_align(bs_t bs)
        {
            int pos = (int)h264e_bs_get_pos_bits(bs);

            h264e_bs_put_bits(bs, (uint)(-pos & 7), 0);
            return((uint)(pos + (-pos & 7)));
        }
示例#2
0
        static void copy_bits(bit_reader_t bs, bs_t bd)
        {
            uint cb, bits;
            int  bit_count = remaining_bits(bs);

            while (bit_count > 7)
            {
                cb   = (uint)Math.Min(bit_count - 7, 8);
                bits = get_bits(bs, (int)cb);
                h264e_bs_put_bits(bd, cb, bits);
                bit_count -= (int)cb;
            }

            // cut extra zeros after stop-bit
            bits = get_bits(bs, bit_count);
            for (; (bit_count != 0) && ((~bits & 1) != 0); bit_count--)
            {
                bits >>= 1;
            }

            if (bit_count != 0)
            {
                h264e_bs_put_bits(bd, (uint)bit_count, bits);
            }
        }
示例#3
0
 private static unsafe void h264e_bs_init_bits(bs_t bs, void *data)
 {
     bs.origin = (uint *)data;
     bs.buf    = bs.origin;
     bs.shift  = 32;
     bs.cache  = 0;
 }
示例#4
0
        static unsafe uint h264e_bs_get_pos_bits(bs_t bs)
        {
            uint pos_bits = (uint)((bs.buf - bs.origin) * 32);

            pos_bits += (uint)(32 - bs.shift);
            Debug.Assert((int)pos_bits >= 0);
            return(pos_bits);
        }
示例#5
0
        static void h264e_bs_put_golomb(bs_t bs, uint val)
        {
            int  size = 0;
            uint t    = val + 1;

            do
            {
                size++;
                t = t >> 1;
            } while (t != 0);

            h264e_bs_put_bits(bs, (uint)(2 * size - 1), val + 1);
        }
示例#6
0
        static unsafe void h264e_bs_put_bits(bs_t bs, uint n, uint val)
        {
            Debug.Assert(((int)val >> (int)n) == 0);
            bs.shift -= (int)n;
            Debug.Assert((int)n <= 32);
            if (bs.shift < 0)
            {
                Debug.Assert(-bs.shift < 32);
                bs.cache |= (int)val >> -bs.shift;
                *bs.buf++ = SWAP32(bs.cache);
                bs.shift = 32 + bs.shift;
                bs.cache = 0;
            }

            bs.cache |= (int)val << bs.shift;
        }
示例#7
0
        static unsafe int change_sps_id(bit_reader_t bs, bs_t bd, int new_id, int *old_id)
        {
            uint bits, sps_id, i, bytes;

            for (i = 0; i < 3; i++)
            {
                bits = get_bits(bs, 8);
                h264e_bs_put_bits(bd, 8, bits);
            }

            sps_id = (uint)ue_bits(bs);  // max = 31

            *old_id = (int)sps_id;
            sps_id = (uint)new_id;
            Debug.Assert(sps_id <= 31);

            h264e_bs_put_golomb(bd, sps_id);
            copy_bits(bs, bd);

            bytes = h264e_bs_byte_align(bd) / 8;
            h264e_bs_flush(bd);
            return((int)bytes);
        }
示例#8
0
        private static unsafe int transcode_nalu(h264_sps_id_patcher_t h, byte *src, int nalu_bytes, byte *dst)
        {
            int old_id;

            bit_reader_t bst = new bit_reader_t();
            bs_t         bdt = new bs_t();

            bit_reader_t bs           = new bit_reader_t();
            bs_t         bd           = new bs_t();
            int          payload_type = src[0] & 31;

            *dst = *src;
            h264e_bs_init_bits(bd, dst + 1);
            init_bits(bs, src + 1, (uint)nalu_bytes - 1);
            h264e_bs_init_bits(bdt, dst + 1);
            init_bits(bst, src + 1, (uint)nalu_bytes - 1);

            switch (payload_type)
            {
            case 7:
            {
                int cb = change_sps_id(bst, bdt, 0, &old_id);
                int id = find_mem_cache(h.sps_cache, h.sps_bytes, MINIMP4_MAX_SPS, dst + 1, cb);
                if (id == -1)
                {
                    return(0);
                }

                h.map_sps[old_id] = id;
                change_sps_id(bs, bd, id, &old_id);
            }
            break;

            case 8:
            {
                int cb = patch_pps(h, bst, bdt, 0, &old_id);
                int id = find_mem_cache(h.pps_cache, h.pps_bytes, MINIMP4_MAX_PPS, dst + 1, cb);
                if (id == -1)
                {
                    return(0);
                }

                h.map_pps[old_id] = id;
                patch_pps(h, bs, bd, id, &old_id);
            }
            break;

            case 1:
            case 2:
            case 5:
                patch_slice_header(h, bs, bd);
                break;

            default:
                memcpy(dst, src, nalu_bytes);
                return(nalu_bytes);
            }

            nalu_bytes = (int)(1 + h264e_bs_byte_align(bd) / 8);
            h264e_bs_flush(bd);

            return(nalu_bytes);
        }
示例#9
0
        private static unsafe void patch_slice_header(h264_sps_id_patcher_t h, bit_reader_t bs, bs_t bd)
        {
            uint first_mb_in_slice = (uint)ue_bits(bs);
            uint slice_type        = (uint)ue_bits(bs);
            uint pps_id            = (uint)ue_bits(bs);

            pps_id = (uint)h.map_pps[pps_id];

            Debug.Assert(pps_id <= 255);

            h264e_bs_put_golomb(bd, first_mb_in_slice);
            h264e_bs_put_golomb(bd, slice_type);
            h264e_bs_put_golomb(bd, pps_id);
            copy_bits(bs, bd);
        }
示例#10
0
        private static unsafe int patch_pps(h264_sps_id_patcher_t h, bit_reader_t bs, bs_t bd, int new_pps_id,
                                            int *old_id)
        {
            int  bytes;
            uint pps_id = (uint)ue_bits(bs);  // max = 255
            uint sps_id = (uint)ue_bits(bs);  // max = 31

            *old_id = (int)pps_id;
            sps_id = (uint)h.map_sps[sps_id];
            pps_id = (uint)new_pps_id;

            Debug.Assert(sps_id <= 31);
            Debug.Assert(pps_id <= 255);

            h264e_bs_put_golomb(bd, pps_id);
            h264e_bs_put_golomb(bd, sps_id);
            copy_bits(bs, bd);

            bytes = (int)h264e_bs_byte_align(bd) / 8;
            h264e_bs_flush(bd);
            return(bytes);
        }
示例#11
0
 static unsafe void h264e_bs_flush(bs_t bs)
 {
     *bs.buf = SWAP32(bs.cache);
 }