Skip to content

Add stream side data #1

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

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion av/stream.pxd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from libc.stdint cimport int64_t
from libc.stdint cimport int64_t, int32_t
cimport libav as lib

from av.codec.context cimport CodecContext
Expand All @@ -13,6 +13,8 @@ cdef class Stream(object):
# Stream attributes.
cdef readonly Container container
cdef readonly dict metadata
cdef readonly int nb_side_data
cdef readonly dict side_data

# CodecContext attributes.
cdef readonly CodecContext codec_context
Expand Down
25 changes: 24 additions & 1 deletion av/stream.pyx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import warnings

from cpython cimport PyWeakref_NewRef
from libc.stdint cimport int64_t, uint8_t
from libc.stdint cimport int64_t, uint8_t, int32_t
from libc.string cimport memcpy
cimport libav as lib

from av.codec.context cimport wrap_codec_context
from av.enum cimport define_enum
from av.error cimport err_check
from av.packet cimport Packet
from av.utils cimport (
Expand All @@ -20,6 +21,12 @@ from av.deprecation import AVDeprecationWarning

cdef object _cinit_bypass_sentinel = object()

SideData = define_enum('SideData', __name__, (
('DISPLAYMATRIX', lib.AV_PKT_DATA_DISPLAYMATRIX ,
"""Display Matrix"""),
# If necessary more can be added from
# https://ffmpeg.org/doxygen/trunk/group__lavc__packet.html#ga9a80bfcacc586b483a973272800edb97
))

cdef Stream wrap_stream(Container container, lib.AVStream *c_stream, CodecContext codec_context):
"""Build an av.Stream for an existing AVStream.
Expand Down Expand Up @@ -83,6 +90,16 @@ cdef class Stream(object):
if self.codec_context:
self.codec_context.stream_index = stream.index

self.nb_side_data = stream.nb_side_data
self.side_data = {}

if self.nb_side_data:
for i in range(self.nb_side_data):
# Get side_data that we know how to get
if SideData.get(stream.side_data[i].type) == 'DISPLAYMATRIX':
# Use dumpsidedata maybe here I guess : https://www.ffmpeg.org/doxygen/trunk/dump_8c_source.html#l00430
self.side_data['DISPLAYMATRIX'] = lib.av_display_rotation_get(<const int32_t *>stream.side_data[i].data)

self.metadata = avdict_to_dict(
stream.metadata,
encoding=self.container.metadata_encoding,
Expand All @@ -107,6 +124,12 @@ cdef class Stream(object):
AVDeprecationWarning
)


if name == 'side_data':
return self.side_data
elif name == 'nb_side_data':
return self.nb_side_data

# Convenience getter for codec context properties.
if self.codec_context is not None:
return getattr(self.codec_context, name)
Expand Down
40 changes: 40 additions & 0 deletions include/libavcodec/avcodec.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,46 @@ cdef extern from "libavcodec/avcodec.h" nogil:

cdef int AV_NUM_DATA_POINTERS

cdef enum AVPacketSideDataType:
AV_PKT_DATA_PALETTE
AV_PKT_DATA_NEW_EXTRADATA
AV_PKT_DATA_PARAM_CHANGE
AV_PKT_DATA_H263_MB_INFO
AV_PKT_DATA_REPLAYGAIN
AV_PKT_DATA_DISPLAYMATRIX
AV_PKT_DATA_STEREO3D
AV_PKT_DATA_AUDIO_SERVICE_TYPE
AV_PKT_DATA_QUALITY_STATS
AV_PKT_DATA_FALLBACK_TRACK
AV_PKT_DATA_CPB_PROPERTIES
AV_PKT_DATA_SKIP_SAMPLES
AV_PKT_DATA_JP_DUALMONO
AV_PKT_DATA_STRINGS_METADATA
AV_PKT_DATA_SUBTITLE_POSITION
AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL
AV_PKT_DATA_WEBVTT_IDENTIFIER
AV_PKT_DATA_WEBVTT_SETTINGS
AV_PKT_DATA_METADATA_UPDATE
AV_PKT_DATA_MPEGTS_STREAM_ID
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
AV_PKT_DATA_SPHERICAL
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
AV_PKT_DATA_A53_CC
AV_PKT_DATA_ENCRYPTION_INIT_INFO
AV_PKT_DATA_ENCRYPTION_INFO
AV_PKT_DATA_AFD
AV_PKT_DATA_PRFT
AV_PKT_DATA_ICC_PROFILE
AV_PKT_DATA_DOVI_CONF
AV_PKT_DATA_S12M_TIMECODE
AV_PKT_DATA_DYNAMIC_HDR10_PLUS
AV_PKT_DATA_NB

cdef struct AVPacketSideData:
uint8_t *data;
size_t size;
AVPacketSideDataType type;

cdef enum AVFrameSideDataType:
AV_FRAME_DATA_PANSCAN
AV_FRAME_DATA_A53_CC
Expand Down
4 changes: 4 additions & 0 deletions include/libavformat/avformat.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ cdef extern from "libavformat/avformat.h" nogil:
AVRational r_frame_rate
AVRational sample_aspect_ratio

int nb_side_data
AVPacketSideData *side_data


# http://ffmpeg.org/doxygen/trunk/structAVIOContext.html
cdef struct AVIOContext:
unsigned char* buffer
Expand Down
5 changes: 4 additions & 1 deletion include/libavutil/avutil.pxd
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from libc.stdint cimport int64_t, uint8_t, uint64_t
from libc.stdint cimport int64_t, uint8_t, uint64_t, int32_t


cdef extern from "libavutil/mathematics.h" nogil:
pass

cdef extern from "libavutil/display.h" nogil:
cdef double av_display_rotation_get(const int32_t matrix[9])

cdef extern from "libavutil/rational.h" nogil:
cdef int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)

Expand Down
13 changes: 13 additions & 0 deletions tests/test_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,16 @@ def test_selection(self):
self.assertEqual([video], container.streams.get(video=(0,)))

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

def test_noside_data(self):
container = av.open(fate_suite("h264/interlaced_crop.mp4"))
video = container.streams.video[0]

self.assertEqual(video.nb_side_data, 0)

def test_side_data(self):
container = av.open(fate_suite("mov/displaymatrix.mov"))
video = container.streams.video[0]

self.assertEqual(video.nb_side_data, 1)
self.assertEqual(video.side_data["DISPLAYMATRIX"], -90.0)