import pickle
with open('/home/thebears/source/infer/dump','rb') as ff:
    dump = pickle.load(ff)



# %%

import av
import numpy as np

#def rtp_to_matrix(rtp_packets):
if True:
    """Convert list of RTP packets to image matrix"""
    
    # Create codec context (adjust codec based on your stream)
    codec = av.CodecContext.create('h264', 'r')  # or 'h265', 'mjpeg', etc.
    
    frames = []
    for _,rtp_packet in ts_data.items():
        # Extract payload (skip RTP header - usually 12 bytes)
        payload = rtp_packet
        # Create packet
        print(len(payload))
        packet = av.Packet(payload)

        try:
            # Decode
            for frame in codec.decode(packet):
                # Convert to numpy array
                img = frame.to_ndarray(format='bgr24')
                frames.append(img)
        except Exception as e:
            print(f"Decode error: {e}")
            continue
    
    # Flush decoder
    for frame in codec.decode(None):
        img = frame.to_ndarray(format='bgr24')
        frames.append(img)
    


# Usage
# rtp_packets = [packet1, packet2, ...]  # Your raw RTP packets
# matrices = rtp_to_matrix(rtp_packets)


# %%

import subprocess
import numpy as np
import cv2
from io import BytesIO

class RTPDepayloader:
    def __init__(self, payload_type):
        """
        payload_type: 96=H264, 26=JPEG, etc.
        """
        self.payload_type = payload_type
        self.buffer = bytearray()
        
    def parse_rtp_header(self, packet):
        """Parse RTP header and return payload"""
        if len(packet) < 12:
            return None
            
        # RTP Header structure (12 bytes minimum)
        # Byte 0: V(2), P(1), X(1), CC(4)
        # Byte 1: M(1), PT(7)
        # Bytes 2-3: Sequence number
        # Bytes 4-7: Timestamp
        # Bytes 8-11: SSRC
        
        version = (packet[0] >> 6) & 0x03
        padding = (packet[0] >> 5) & 0x01
        extension = (packet[0] >> 4) & 0x01
        csrc_count = packet[0] & 0x0F
        
        marker = (packet[1] >> 7) & 0x01
        payload_type = packet[1] & 0x7F
        
        sequence = int.from_bytes(packet[2:4], 'big')
        timestamp = int.from_bytes(packet[4:8], 'big')
        
        # Calculate header size
        header_size = 12 + (csrc_count * 4)
        
        if extension:
            if len(packet) < header_size + 4:
                return None
            ext_len = int.from_bytes(packet[header_size+2:header_size+4], 'big') * 4
            header_size += 4 + ext_len
        
        # Return payload
        payload = packet[header_size:]
        
        return {
            'payload': payload,
            'marker': marker,
            'sequence': sequence,
            'timestamp': timestamp,
            'payload_type': payload_type
        }
    
    def depayload_h264(self, rtp_packets):
        """Depayload H.264 RTP packets to NAL units"""
        nal_units = bytearray()
        
        for packet in rtp_packets:
            parsed = self.parse_rtp_header(packet)
            if not parsed:
                continue
                
            payload = parsed['payload']
            if len(payload) == 0:
                continue
            
            # H.264 RTP payload format (RFC 6184)
            nal_unit_type = payload[0] & 0x1F
            
            if nal_unit_type >= 1 and nal_unit_type <= 23:
                # Single NAL unit
                nal_units.extend(b'\x00\x00\x00\x01')  # Start code
                nal_units.extend(payload)
            elif nal_unit_type == 28:
                # FU-A (Fragmentation Unit)
                fu_header = payload[1]
                start = (fu_header >> 7) & 0x01
                end = (fu_header >> 6) & 0x01
                nal_type = fu_header & 0x1F
                
                if start:
                    # Reconstruct NAL header
                    nal_header = (payload[0] & 0xE0) | nal_type
                    nal_units.extend(b'\x00\x00\x00\x01')
                    nal_units.append(nal_header)
                
                nal_units.extend(payload[2:])
        
        return bytes(nal_units)

def decode_h264_to_matrix(h264_data):
    """Decode H.264 bitstream to image matrix using FFmpeg"""
    
    # Use FFmpeg to decode
    process = subprocess.Popen([
        'ffmpeg',
        '-f', 'h264',
        '-i', 'pipe:0',
        '-f', 'rawvideo',
        '-pix_fmt', 'bgr24',
        'pipe:1'
    ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    stdout, stderr = process.communicate(input=h264_data)
    
    # You need to know dimensions or parse from SPS
    # For now, assume 1920x1080
    width, height = 1920, 1080
    
    if len(stdout) >= width * height * 3:
        frame = np.frombuffer(stdout[:width*height*3], dtype=np.uint8)
        frame = frame.reshape((height, width, 3))
        return frame
    
    return None

# Usage
rtp_packets = [bytes(x) for x in dump]
depayloader = RTPDepayloader(payload_type=96)
# rtp_packets = [...]  # Your raw RTP packets
h264_stream = depayloader.depayload_h264(rtp_packets)
matrix = decode_h264_to_matrix(h264_stream)


# %%


bts = b''
for i in range(10000):
    bts+=process.stdout.read(1024)
    print(i)
# %%
with open('dumpb','wb') as ff:
    ff.write(bts)
# %%
import re
pattern = b'BM'

fcf = [m.start() for m in re.finditer(re.escape(pattern), bts)]


# %%

with open('dumpb','rb') as ff:
    byte_stream = ff.read()[10:]


import struct
import numpy as np
import cv2




# %%
import struct


def read_bmp_frames(stream):
    """Read individual BMP frames from a stream."""
    while True:
        # Read BMP signature (2 bytes)
        signature = stream.read(2)
        if len(signature) < 2:
            break
        
        if signature != b'BM':
            print(f"Warning: Expected 'BM', got {signature}")
            break
        
        # Read file size (4 bytes, little-endian)
        size_bytes = stream.read(4)
        if len(size_bytes) < 4:
            break
        
        file_size = struct.unpack('<I', size_bytes)[0]
        
        # Read the rest of the frame
        remaining_size = file_size - 6  # Already read 6 bytes
        frame_data = stream.read(remaining_size)
        
        if len(frame_data) < remaining_size:
            break
        
        # Complete frame
        complete_frame = signature + size_bytes + frame_data
        yield complete_frame

# Usage
import subprocess as sp

cmd = "ffmpeg -rtsp_transport tcp -i rtsp://admin:marybear@192.168.1.153:554/h264Preview_01_sub -f image2pipe -vcodec bmp -an pipe:1"

# process = sp.Popen(
#         cmd.split(" "),
#         stdout=sp.PIPE,
#         stderr=sp.PIPE,
#     bufsize =512*896*3*3
#     )




import asyncio
import subprocess

async def read_stream():
    """Read subprocess output asynchronously."""
    
    process = await asyncio.create_subprocess_exec(*cmd.split(" "),
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )
    frame_count = 0
    try:
        while True:
            # Read up to 65KB at a time
            chunk = await process.stdout.read(65536)
            print('chunk')
            if not chunk:
                break
            
            frame_count += len(chunk)
            print(f"Read {len(chunk)} bytes (total: {frame_count})")
    
    except asyncio.CancelledError:
        process.kill()
        await process.wait()
    
    return frame_count

# Run
frame_count = asyncio.run(read_stream())
# %%





# %%

import numpy as np
fr = next(gen)
import cv2

# %%

import av
import numpy as np

def rtp_to_matrix(rtp_packets):
    """Convert list of RTP packets to image matrix"""
    
    # Create codec context (adjust codec based on your stream)
    codec = av.CodecContext.create('h264', 'r')  # or 'h265', 'mjpeg', etc.
    
    frames = []
    for rtp_packet in rtp_packets:
        # Extract payload (skip RTP header - usually 12 bytes)
        payload = rtp_packet[12:]
        
        # Create packet
        packet = av.Packet(payload)
        
        try:
            # Decode
            for frame in codec.decode(packet):
                # Convert to numpy array
                img = frame.to_ndarray(format='bgr24')
                frames.append(img)
        except Exception as e:
            print(f"Decode error: {e}")
            continue
    
    # Flush decoder
    for frame in codec.decode(None):
        img = frame.to_ndarray(format='bgr24')
        frames.append(img)
    
    return frames

# Usage
# rtp_packets = [packet1, packet2, ...]  # Your raw RTP packets
# matrices = rtp_to_matrix(rtp_packets)
