Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • P PyAV
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 37
    • Issues 37
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 26
    • Merge requests 26
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • PyAV
  • PyAV
  • Issues
  • #1005
Closed
Open
Issue created Jul 06, 2022 by Administrator@rootContributor0 of 6 checklist items completed0/6 checklist items

VideoStream.rate and VideoStream.framerate no longer available

Created by: uvjustin

Overview

After #910 was merged, VideoStream.rate and VideoStream.framerate are no longer populated from an InputContainer.

Expected behavior

These fields should be populated.

Investigation

Using the below test_streams.py file (augment the current test_streams.py with 2 additional lines), the test case now fails. Pre #910 it succeeded.

import av

from .common import TestCase, fate_suite


class TestStreams(TestCase):
    def test_stream_tuples(self):

        for fate_name in ("h264/interlaced_crop.mp4",):

            container = av.open(fate_suite(fate_name))

            video_streams = tuple([s for s in container.streams if s.type == "video"])
            self.assertEqual(video_streams, container.streams.video)

            audio_streams = tuple([s for s in container.streams if s.type == "audio"])
            self.assertEqual(audio_streams, container.streams.audio)

    def test_selection(self):

        container = av.open(fate_suite("h264/interlaced_crop.mp4"))
        video = container.streams.video[0]
        # audio_stream = container.streams.audio[0]
        # audio_streams = list(container.streams.audio[0:2])

        self.assertEqual([video], container.streams.get(video=0))
        self.assertEqual([video], container.streams.get(video=(0,)))
        self.assertIsNotNone(video.rate)
        self.assertIsNotNone(video.framerate)

        # TODO: Find something in the fate suite with video, audio, and subtitles.

Actual behavior

fails

Research

I have done the following:

  • Checked the PyAV documentation
  • Searched on Google
  • Searched on Stack Overflow
  • Looked through old GitHub issues
  • Asked on PyAV Gitter
  • ... and waited 72 hours for a response.

Additional context

This is because the InputContainer's cinit was changed to initialize a separate AVCodecContext, and the parameters are copied over from the stream's AVCodecParameters using lib.avcodec_parameters_to_context(). However, AVCodecParameters does not include a video framerate, so the AVCodecContext never has the framerate field initialized for video streams. Note that AudioStream does not have this issue as the sample_rate field gets copied properly. As mentioned on #910, we can either solve this by:

  1. Copying the stream's avg_frame_rate into codec_context's framerate during InputContainer cinit, continuing to rely on passthrough into the codec_context when the properties are acccessed, or
  2. Adding the rate/framerate properties directly to VideoStream (pointing them to the AVStream's avg_frame_rate). There's a broader architectural theme here - continue relying on passthrough attribute access or not?
Assignee
Assign to
Time tracking