NVIDIA / VideoProcessingFramework

Set of Python bindings to C++ libraries which provides full HW acceleration for video decoding, encoding and GPU-accelerated color space and pixel format conversions
Apache License 2.0
1.3k stars 231 forks source link

The video generated by VPF encoder has no bitrate and duration information. #96

Closed TracelessLe closed 4 years ago

TracelessLe commented 4 years ago

Describe the bug I run the SampleDecode.py and SampleEncode.py, but the output video by the encode process is weird. The video generated by VPF encoder has no bitrate and duration information, it can't be played by video player or chrome browser. I input it to ffmpeg and it shows the video information:

Input #0, h264, from 'test-gpu.mp4':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: h264 (High), yuv420p(progressive), 720x1280 [SAR 1:1 DAR 9:16], 25 fps, 25 tbr, 1200k tbn, 50 tbc

To Reproduce Steps to reproduce the behavior:

  1. Run SampleDecode.py on a normal h264 video and generate a raw NV12 file.
  2. Run SampleEncode.py using the a raw NV12 file to generate a h264(or mp4) file.
  3. Try to open the h264(or mp4) video using player but failed.
  4. Using 'ffmpeg -i output.mp4' command and find the generated video has no bitrate and duration.

Expected behavior To generate a normal h264 video that QuickTimePlayer or Chrome browser can play.

Screenshots image

Desktop:

Additional context By the way , I find a player name sPlayer on mac can play the generated video, it shows that the video palyed vert fast and no time control bar. image

The output video is attached (be zipped) as below: output.mp4.zip

I integrate the SampleDecode.py and SampleEncode.py and finally code I used is attached as below:

SampleDecodeEncode.py.zip

rarzumanyan commented 4 years ago

Hi @TracelessLe

VPF generates Annex.B elementary bitstream video which isn't put into any container. So by giving output file *.mp4 extension, it won't change the output file structure. This is done intentionally and users have to mux video output themselves.

P. S. VLC can play Annex.B videos without issues.

TracelessLe commented 4 years ago

Hi @TracelessLe

VPF generates Annex.B elementary bitstream video which isn't put into any container. So by giving output file *.mp4 extension, it won't change the output file structure. This is done intentionally and users have to mux video output themselves.

P. S. VLC can play Annex.B videos without issues.

Thank you for your great help and support! I solve the problem. VPF is an excellent framework! Thans for your efforts!

wykvictor commented 2 years ago

Hi @TracelessLe VPF generates Annex.B elementary bitstream video which isn't put into any container. So by giving output file *.mp4 extension, it won't change the output file structure. This is done intentionally and users have to mux video output themselves. P. S. VLC can play Annex.B videos without issues.

Thank you for your great help and support! I solve the problem. VPF is an excellent framework! Thans for your efforts!

Hi, @TracelessLe , I encountered the same problem. Could you pls share the way to mux the output video? As far as I know, ffmpeg command can do this( ffmpeg -i output.h264 -c copy output.mp4). But this will cost time to read the bytes(output.h264) from disk and additional time to launch the ffmpeg process. My use of the VPF is to save time encoding the video, so is there any 3-party interface of doing video-mux efficiently? cc @rarzumanyan Thanks!

rarzumanyan commented 2 years ago

Hi @wykvictor

PyAV can be used for that, take a look here.

wykvictor commented 2 years ago

Hi @wykvictor

PyAV can be used for that, take a look here.

Thanks! I tried PyAV and it worded fine. Here is the code snippet, so everyone else could refer to it.

# 1. init
dstFile = av.open(dstFilePath, 'w')
out_stream = dstFile.add_stream('h264', rate = 25)
out_stream.width = w
out_stream.height = h

# 2. mux
encByteArray = bytearray(encFrame)  # encFrame from EncodeSingleSurface
pkt = av.packet.Packet(encByteArray)
pkt.pts = pts_time
pkt.dts = pts_time
pkt.stream = out_stream  # attach pkt to the stream
dstFile.mux(pkt)
rarzumanyan commented 2 years ago

Thank for the code snippet, @wykvictor that's super useful. I'll add this to wiki if you don't mind.

wykvictor commented 2 years ago

Thank for the code snippet, @wykvictor that's super useful. I'll add this to wiki if you don't mind.

It's fine, very happy if this can help others