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
  • #489
Closed
Open
Issue created Feb 26, 2019 by Administrator@rootContributor

Using Bit Stream Filters

Created by: hunterjm

I am trying to convert an MP4 H264 stream to Annex-B for use in a MPEGTS output container. I am using the MP4 generated video file located in the docs under numpy for my reproduction example. I am getting an error saying that the stream is invalid, and needs to be in Annex B using -bsf:v h264_mp4toannexb

Error

H.264 bitstream malformed, no startcode found, use the video bitstream filter 'h264_mp4toannexb' to fix it ('-bsf:v h264_mp4toannexb' option with ffmpeg)

Reproduction code:

import io

import numpy as np
import av

duration = 4
fps = 24
total_frames = duration * fps

mp4 = io.BytesIO()
mp4.name = 'test.mp4'
container = av.open(mp4, mode='w')

stream = container.add_stream('libx264', rate=fps)
stream.width = 480
stream.height = 320
stream.pix_fmt = 'yuv420p'

for frame_i in range(total_frames):

    img = np.empty((480, 320, 3))
    img[:, :, 0] = 0.5 + 0.5 * np.sin(2 * np.pi * (0 / 3 + frame_i / total_frames))
    img[:, :, 1] = 0.5 + 0.5 * np.sin(2 * np.pi * (1 / 3 + frame_i / total_frames))
    img[:, :, 2] = 0.5 + 0.5 * np.sin(2 * np.pi * (2 / 3 + frame_i / total_frames))

    img = np.round(255 * img).astype(np.uint8)
    img = np.clip(img, 0, 255)

    frame = av.VideoFrame.from_ndarray(img, format='rgb24')
    for packet in stream.encode(frame):
        container.mux(packet)

# Flush stream
for packet in stream.encode():
    container.mux(packet)

# Close the file
container.close()


# Convert to mpegts
input_ = av.open(mp4, 'r')
input_stream = input_.streams.video[0]
output_file = io.BytesIO()
output_file.name = 'test.ts'
output = av.open(output_file, 'w', format='mpegts')
output_stream = output.add_stream('h264', input_stream.rate)

for packet in input_.demux(input_stream):
    # We need to skip the "flushing" packets that `demux` generates.
    if packet.dts is None:
        continue

    # We need to assign the packet to the new stream.
    packet.stream = output_stream

    output.mux(packet)

output.close()
Assignee
Assign to
Time tracking