예제 #1
0
    def test_reformat_colourspace(self):

        # This is allowed.
        frame = VideoFrame(640, 480, 'rgb24')
        frame.reformat(src_colorspace=None, dst_colorspace='smpte240')

        # I thought this was not allowed, but it seems to be.
        frame = VideoFrame(640, 480, 'yuv420p')
        frame.reformat(src_colorspace=None, dst_colorspace='smpte240')
예제 #2
0
 def test_reformat_pts(self):
     frame = VideoFrame(640, 480, 'rgb24')
     frame.pts = 123
     frame.time_base = '456/1'  # Just to be different.
     frame = frame.reformat(320, 240)
     self.assertEqual(frame.pts, 123)
     self.assertEqual(frame.time_base, 456)
예제 #3
0
    def test_stream_index(self):
        with av.open(self.sandboxed("output.mov"), "w") as output:
            vstream = output.add_stream("mpeg4", 24)
            vstream.pix_fmt = "yuv420p"
            vstream.width = 320
            vstream.height = 240

            astream = output.add_stream("mp2", 48000)
            astream.channels = 2
            astream.format = "s16"

            self.assertEqual(vstream.index, 0)
            self.assertEqual(astream.index, 1)

            vframe = VideoFrame(320, 240, "yuv420p")
            vpacket = vstream.encode(vframe)[0]

            self.assertIs(vpacket.stream, vstream)
            self.assertEqual(vpacket.stream_index, 0)

            for i in range(10):
                if astream.frame_size != 0:
                    frame_size = astream.frame_size
                else:
                    # decoder didn't indicate constant frame size
                    frame_size = 1000
                aframe = AudioFrame("s16", "stereo", samples=frame_size)
                aframe.rate = 48000
                apackets = astream.encode(aframe)
                if apackets:
                    apacket = apackets[0]
                    break

            self.assertIs(apacket.stream, astream)
            self.assertEqual(apacket.stream_index, 1)
예제 #4
0
def write_rgb_rotate(output):

    if not Image:
        raise SkipTest()

    output.metadata['title'] = 'container'
    output.metadata['key'] = 'value'

    stream = output.add_stream("mpeg4", 24)
    stream.width = WIDTH
    stream.height = HEIGHT
    stream.pix_fmt = "yuv420p"

    for frame_i in range(DURATION):

        frame = VideoFrame(WIDTH, HEIGHT, 'rgb24')
        image = Image.new('RGB', (WIDTH, HEIGHT), (
            int(255 *
                (0.5 + 0.5 * math.sin(frame_i / DURATION * 2 * math.pi))),
            int(255 * (0.5 + 0.5 * math.sin(frame_i / DURATION * 2 * math.pi +
                                            2 / 3 * math.pi))),
            int(255 * (0.5 + 0.5 * math.sin(frame_i / DURATION * 2 * math.pi +
                                            4 / 3 * math.pi))),
        ))
        frame.planes[0].update(image.tobytes())

        for packet in stream.encode(frame):
            output.mux(packet)

    for packet in stream.encode(None):
        output.mux(packet)

    # Done!
    output.close()
예제 #5
0
    def test_stream_index(self):
        output = av.open(self.sandboxed('output.mov'), 'w')

        vstream = output.add_stream('mpeg4', 24)
        vstream.pix_fmt = 'yuv420p'
        vstream.width = 320
        vstream.height = 240

        astream = output.add_stream('mp2', 48000)
        astream.channels = 2
        astream.format = 's16'

        self.assertEqual(vstream.index, 0)
        self.assertEqual(astream.index, 1)

        vframe = VideoFrame(320, 240, 'yuv420p')
        vpacket = vstream.encode(vframe)[0]

        self.assertIs(vpacket.stream, vstream)
        self.assertEqual(vpacket.stream_index, 0)

        for i in range(10):
            aframe = AudioFrame('s16', 'stereo', samples=astream.frame_size)
            aframe.rate = 48000
            apackets = astream.encode(aframe)
            if apackets:
                apacket = apackets[0]
                break

        self.assertIs(apacket.stream, astream)
        self.assertEqual(apacket.stream_index, 1)
예제 #6
0
    def generatePreview(self, n):
        try:
            return next(self.zonecopy.iterFrames(n))

        except StopIteration:
            return VideoFrame(width=self.filtercopy.width,
                              height=self.filtercopy.height)
예제 #7
0
 def test_rgb24_planes(self):
     frame = VideoFrame(640, 480, 'rgb24')
     self.assertEqual(len(frame.planes), 1)
     self.assertEqual(frame.planes[0].width, 640)
     self.assertEqual(frame.planes[0].height, 480)
     self.assertEqual(frame.planes[0].line_size, 640 * 3)
     self.assertEqual(frame.planes[0].buffer_size, 640 * 480 * 3)
예제 #8
0
    def test_to_image_rgb24(self):
        sizes = [
            (318, 238),
            (320, 240),
            (500, 500),
        ]
        for width, height in sizes:
            frame = VideoFrame(width, height, format='rgb24')

            # fill video frame data
            for plane in frame.planes:
                ba = bytearray(plane.buffer_size)
                pos = 0
                for row in range(height):
                    for i in range(plane.line_size):
                        ba[pos] = i % 256
                        pos += 1
                plane.update(ba)

            # construct expected image data
            expected = bytearray(height * width * 3)
            pos = 0
            for row in range(height):
                for i in range(width * 3):
                    expected[pos] = i % 256
                    pos += 1

            img = frame.to_image()
            self.assertEqual(img.size, (width, height))
            self.assertEqual(img.tobytes(), expected)
예제 #9
0
    def test_buffer(self):
        if not hasattr(__builtins__, 'buffer'):
            raise SkipTest()

        frame = VideoFrame(640, 480, 'rgb24')
        frame.planes[0].update(b'01234' + (b'x' * (640 * 480 * 3 - 5)))
        buf = buffer(frame.planes[0])  # noqa
        self.assertEqual(buf[1], b'1')
        self.assertEqual(buf[:7], b'01234xx')
예제 #10
0
 def create_video_frame(self, width, height, pts, format='yuv420p', time_base=VIDEO_TIME_BASE):
     """
     Create a single blank video frame.
     """
     frame = VideoFrame(width=width, height=height, format=format)
     for p in frame.planes:
         p.update(bytes(p.buffer_size))
     frame.pts = pts
     frame.time_base = time_base
     return frame
예제 #11
0
 def test_buffer(self):
     try:
         buffer
     except NameError:
         raise SkipTest()
     frame = VideoFrame(640, 480, 'rgb24')
     frame.planes[0].update(b'01234' + (b'x' * (640 * 480 * 3 - 5)))
     buf = buffer(frame.planes[0])
     self.assertEqual(buf[1], b'1')
     self.assertEqual(buf[:7], b'01234xx')
예제 #12
0
 def test_memoryview_read(self):
     frame = VideoFrame(640, 480, "rgb24")
     frame.planes[0].update(b"01234" + (b"x" * (640 * 480 * 3 - 5)))
     mem = memoryview(frame.planes[0])
     self.assertEqual(mem.ndim, 1)
     self.assertEqual(mem.shape, (640 * 480 * 3, ))
     self.assertFalse(mem.readonly)
     self.assertEqual(mem[1], 49)
     self.assertEqual(mem[:7], b"01234xx")
     mem[1] = 46
     self.assertEqual(mem[:7], b"0.234xx")
예제 #13
0
 def test_yuv420p_planes(self):
     frame = VideoFrame(640, 480, 'yuv420p')
     self.assertEqual(len(frame.planes), 3)
     self.assertEqual(frame.planes[0].width, 640)
     self.assertEqual(frame.planes[0].height, 480)
     self.assertEqual(frame.planes[0].line_size, 640)
     self.assertEqual(frame.planes[0].buffer_size, 640 * 480)
     for i in range(1, 3):
         self.assertEqual(frame.planes[i].width, 320)
         self.assertEqual(frame.planes[i].height, 240)
         self.assertEqual(frame.planes[i].line_size, 320)
         self.assertEqual(frame.planes[i].buffer_size, 320 * 240)
예제 #14
0
    def test_basic_to_nd_array(self):
        frame = VideoFrame(640, 480, 'rgb24')
        with warnings.catch_warnings(record=True) as recorded:
            array = frame.to_nd_array()
        self.assertEqual(array.shape, (480, 640, 3))

        # check deprecation warning
        self.assertEqual(len(recorded), 1)
        self.assertEqual(recorded[0].category, AttributeRenamedWarning)
        self.assertEqual(
            str(recorded[0].message),
            'VideoFrame.to_nd_array is deprecated; please use VideoFrame.to_ndarray.'
        )
예제 #15
0
    def test_memoryview_read(self):
        if not hasattr(__builtins__, 'memoryview'):
            raise SkipTest()

        frame = VideoFrame(640, 480, 'rgb24')
        frame.planes[0].update(b'01234' + (b'x' * (640 * 480 * 3 - 5)))
        mem = memoryview(frame.planes[0])  # noqa
        self.assertEqual(mem.ndim, 1)
        self.assertEqual(mem.shape, (640 * 480 * 3, ))
        self.assertFalse(mem.readonly)
        self.assertEqual(mem[1], 49 if is_py3 else b'1')
        self.assertEqual(mem[:7], b'01234xx')
        mem[1] = 46 if is_py3 else b'.'
        self.assertEqual(mem[:7], b'0.234xx')
예제 #16
0
 def test_yuv420p_planes_align(self):
     # If we request 8-byte alignment for a width which is not a multiple of 8,
     # the line sizes are larger than the plane width.
     frame = VideoFrame(318, 238, 'yuv420p')
     self.assertEqual(len(frame.planes), 3)
     self.assertEqual(frame.planes[0].width, 318)
     self.assertEqual(frame.planes[0].height, 238)
     self.assertEqual(frame.planes[0].line_size, 320)
     self.assertEqual(frame.planes[0].buffer_size, 320 * 238)
     for i in range(1, 3):
         self.assertEqual(frame.planes[i].width, 159)
         self.assertEqual(frame.planes[i].height, 119)
         self.assertEqual(frame.planes[i].line_size, 160)
         self.assertEqual(frame.planes[i].buffer_size, 160 * 119)
예제 #17
0
 def test_memoryview_read(self):
     try:
         memoryview
     except NameError:
         raise SkipTest()
     frame = VideoFrame(640, 480, 'rgb24')
     frame.planes[0].update(b'01234' + (b'x' * (640 * 480 * 3 - 5)))
     mem = memoryview(frame.planes[0])
     self.assertEqual(mem.ndim, 1)
     self.assertEqual(mem.shape, (640 * 480 * 3, ))
     self.assertFalse(mem.readonly)
     self.assertEqual(mem[1], 49 if is_py3 else b'1')
     self.assertEqual(mem[:7], b'01234xx')
     mem[1] = 46 if is_py3 else b'.'
     self.assertEqual(mem[:7], b'0.234xx')
예제 #18
0
    def test_reformat_pixel_format_align(self):
        height = 480
        for width in range(2, 258, 2):
            frame_yuv = VideoFrame(width, height, "yuv420p")
            for plane in frame_yuv.planes:
                plane.update(b"\xff" * plane.buffer_size)

            expected_rgb = numpy.zeros(shape=(height, width, 3),
                                       dtype=numpy.uint8)
            expected_rgb[:, :, 0] = 255
            expected_rgb[:, :, 1] = 124
            expected_rgb[:, :, 2] = 255

            frame_rgb = frame_yuv.reformat(format="rgb24")
            self.assertNdarraysEqual(frame_rgb.to_ndarray(), expected_rgb)
예제 #19
0
    async def recv(self) -> Frame:
        """
        Receive the next :class:`~av.video.frame.VideoFrame`.

        The base implementation just reads a 640x480 green frame at 30fps,
        subclass :class:`VideoStreamTrack` to provide a useful implementation.
        """
        pts, time_base = await self.next_timestamp()

        frame = VideoFrame(width=640, height=480)
        for p in frame.planes:
            p.update(bytes(p.buffer_size))
        frame.pts = pts
        frame.time_base = time_base
        return frame
예제 #20
0
파일: vpx.py 프로젝트: ai-mocap/aiortc
    def decode(self, encoded_frame: JitterFrame) -> List[VideoFrameExt]:
        frames: List[VideoFrameExt] = []
        result = lib.vpx_codec_decode(
            self.codec,
            encoded_frame.data,
            len(encoded_frame.data),
            ffi.NULL,
            lib.VPX_DL_REALTIME,
        )
        if result == lib.VPX_CODEC_OK:
            it = ffi.new("vpx_codec_iter_t *")
            while True:
                img = lib.vpx_codec_get_frame(self.codec, it)
                if not img:
                    break
                assert img.fmt == lib.VPX_IMG_FMT_I420

                frame = VideoFrame(width=img.d_w, height=img.d_h)
                frame.pts = encoded_frame.timestamp
                frame.time_base = VIDEO_TIME_BASE
                frame_ext = VideoFrameExt(
                    frame=frame,
                    ntp_timestamp=encoded_frame.ntp_timestamp + timedelta(
                        seconds=encoded_frame.rtp_diff / VIDEO_CLOCK_RATE),
                    encoded_frame=encoded_frame,
                )

                for p in range(3):
                    i_stride = img.stride[p]
                    i_buf = ffi.buffer(img.planes[p], i_stride * img.d_h)
                    i_pos = 0

                    o_stride = frame.planes[p].line_size
                    o_buf = memoryview(cast(bytes, frame.planes[p]))
                    o_pos = 0

                    div = p and 2 or 1
                    for r in range(0, img.d_h // div):
                        o_buf[o_pos:o_pos + o_stride] = i_buf[i_pos:i_pos +
                                                              o_stride]
                        i_pos += i_stride
                        o_pos += o_stride

                frames.append(frame_ext)

        return frames
예제 #21
0
    def test_reformat_pixel_format_align(self):
        height = 480
        for width in range(2, 258, 2):
            frame_yuv = VideoFrame(width, height, 'yuv420p')
            for plane in frame_yuv.planes:
                plane.update(b'\xff' * plane.buffer_size)

            expected_rgb = numpy.zeros(shape=(height, width, 3),
                                       dtype=numpy.uint8)
            expected_rgb[:, :, 0] = 255
            expected_rgb[:, :, 1] = 124
            expected_rgb[:, :, 2] = 255

            frame_rgb = frame_yuv.reformat(format='rgb24')
            array_rgb = frame_rgb.to_ndarray()
            self.assertEqual(array_rgb.shape, (height, width, 3))
            self.assertTrue((array_rgb == expected_rgb).all())
예제 #22
0
    def test_encoding_with_pts(self):
        path = self.sandboxed("video_with_pts.mov")

        with av.open(path, "w") as output:
            stream = output.add_stream("libx264", 24)
            stream.width = WIDTH
            stream.height = HEIGHT
            stream.pix_fmt = "yuv420p"

            for i in range(DURATION):
                frame = VideoFrame(WIDTH, HEIGHT, "rgb24")
                frame.pts = i * 2000
                frame.time_base = Fraction(1, 48000)

                for packet in stream.encode(frame):
                    self.assertEqual(packet.time_base, Fraction(1, 24))
                    output.mux(packet)

            for packet in stream.encode(None):
                self.assertEqual(packet.time_base, Fraction(1, 24))
                output.mux(packet)
예제 #23
0
파일: vpx.py 프로젝트: quito418/aiortc-1
    def decode(self, encoded_frame):
        frames = []
        result = lib.vpx_codec_decode(
            self.codec,
            encoded_frame.data,
            len(encoded_frame.data),
            ffi.NULL,
            lib.VPX_DL_REALTIME,
        )
        if result == lib.VPX_CODEC_OK:
            it = ffi.new("vpx_codec_iter_t *")
            while True:
                img = lib.vpx_codec_get_frame(self.codec, it)
                if not img:
                    break
                assert img.fmt == lib.VPX_IMG_FMT_I420

                frame = VideoFrame(width=img.d_w, height=img.d_h)
                frame.pts = encoded_frame.timestamp
                frame.time_base = VIDEO_TIME_BASE

                for p in range(3):
                    i_stride = img.stride[p]
                    i_buf = ffi.buffer(img.planes[p], i_stride * img.d_h)
                    i_pos = 0

                    o_stride = frame.planes[p].line_size
                    o_buf = memoryview(frame.planes[p])
                    o_pos = 0

                    div = p and 2 or 1
                    for r in range(0, img.d_h // div):
                        o_buf[o_pos:o_pos + o_stride] = i_buf[i_pos:i_pos +
                                                              o_stride]
                        i_pos += i_stride
                        o_pos += o_stride

                frames.append(frame)

        return frames
예제 #24
0
def write_rgb_rotate(output):

    if not Image:
        raise SkipTest()

    output.metadata["title"] = "container"
    output.metadata["key"] = "value"

    stream = output.add_stream("mpeg4", 24)
    stream.width = WIDTH
    stream.height = HEIGHT
    stream.pix_fmt = "yuv420p"

    for frame_i in range(DURATION):

        frame = VideoFrame(WIDTH, HEIGHT, "rgb24")
        image = Image.new(
            "RGB",
            (WIDTH, HEIGHT),
            (
                int(255 *
                    (0.5 + 0.5 * math.sin(frame_i / DURATION * 2 * math.pi))),
                int(255 *
                    (0.5 + 0.5 * math.sin(frame_i / DURATION * 2 * math.pi +
                                          2 / 3 * math.pi))),
                int(255 *
                    (0.5 + 0.5 * math.sin(frame_i / DURATION * 2 * math.pi +
                                          4 / 3 * math.pi))),
            ),
        )
        frame.planes[0].update(image.tobytes())

        for packet in stream.encode(frame):
            output.mux(packet)

    for packet in stream.encode(None):
        output.mux(packet)
예제 #25
0
 def test_null_planes(self):
     frame = VideoFrame()  # yuv420p
     self.assertEqual(len(frame.planes), 0)
예제 #26
0
 def test_reformat_identity(self):
     frame1 = VideoFrame(640, 480, 'rgb24')
     frame2 = frame1.reformat(640, 480, 'rgb24')
     self.assertIs(frame1, frame2)
예제 #27
0
 def test_manual_yuv_constructor(self):
     frame = VideoFrame(640, 480, "yuv420p")
     self.assertEqual(frame.width, 640)
     self.assertEqual(frame.height, 480)
     self.assertEqual(frame.format.name, "yuv420p")
예제 #28
0
 def test_manual_rgb_constructor(self):
     frame = VideoFrame(640, 480, 'rgb24')
     self.assertEqual(frame.width, 640)
     self.assertEqual(frame.height, 480)
     self.assertEqual(frame.format.name, 'rgb24')
예제 #29
0
 def test_basic_to_ndarray(self):
     frame = VideoFrame(640, 480, 'rgb24')
     array = frame.to_ndarray()
     self.assertEqual(array.shape, (480, 640, 3))
예제 #30
0
 def test_null_constructor(self):
     frame = VideoFrame()
     self.assertEqual(frame.width, 0)
     self.assertEqual(frame.height, 0)
     self.assertEqual(frame.format.name, 'yuv420p')