Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

video stream format was changed at scrcpy 2.x . #83

Open
tokoroten opened this issue Oct 9, 2024 · 0 comments
Open

video stream format was changed at scrcpy 2.x . #83

tokoroten opened this issue Oct 9, 2024 · 0 comments

Comments

@tokoroten
Copy link
Contributor

tokoroten commented Oct 9, 2024

video stream format was changed at scrcpy 2.x .

https://github.com/Genymobile/scrcpy/blob/master/doc/develop.md#video-and-audio

  • at first, 12 byte frame-header is coming
  • and next, frame data.

current implementation is not use this 12 byte header.
and PyAV codec will be ignore this header.

https://github.com/leng-yue/py-scrcpy-client/blob/main/scrcpy/core.py#L236-L248

I think, #75 is would occurred by this.

This is my forked code.
Bat too many changes to merge, so this is for reference.

        SC_PACKET_FLAG_CONFIG = 1 << 63
        SC_PACKET_FLAG_KEY_FRAME = 1 << 62
        SC_PACKET_PTS_MASK = (1 << 62) - 1

        self.__video_socket.setblocking(True)

        while self.alive:
            try:
                video_header = self.__video_socket.recv(12)
                if len(video_header) == 0:
                    raise ConnectionError("Video stream is disconnected")
                if len(video_header) != 12:
                    raise ConnectionError("Video header is less than 12 bytes")

                (pts, data_packet_length) = struct.unpack(">QL", video_header)
                config_flag = pts & SC_PACKET_FLAG_CONFIG
                keyframe_flag = pts & SC_PACKET_FLAG_KEY_FRAME
                pts = pts & SC_PACKET_PTS_MASK 

                if config_flag:
                    # todo: manage config flag
                    print("video config flag comming!")
                    self.__send_to_listeners(EVENT_FRAME_CONFIG_CHANGE) 
                    
                video_data = b""
                while True:
                    revived_data = self.__video_socket.recv(data_packet_length - len(video_data))
                    if len(revived_data) == 0:
                        raise ConnectionError("Video stream is disconnected")
                    
                    if len(video_data) == 0:
                        video_data = revived_data
                    else:
                        video_data += revived_data

                    if len(video_data) == data_packet_length:
                        break

                packets = codec.parse(video_data)
                for packet in packets:
                    frames = codec.decode(packet)
                    for frame in frames:
                        if pts == 0:
                            continue

                        frame = frame.to_ndarray(format="bgr24")
                        if self.flip:
                            frame = frame[:, ::-1, :]
                        self.last_frame = frame
                        self.resolution = (frame.shape[1], frame.shape[0])
                        self.__send_to_listeners(EVENT_FRAME, frame, pts)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant