# Convert h264 file to mp4 with \`cv::cudacodec\`

**URL:** <https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313>\
**Category:** C++\
**Tags:** gpu, cuda, videoio\
**Created:** [August 21, 2023, 1:52pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313 "2023-08-21T13:52:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [August 21, 2023, 1:52pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/1 "2023-08-21T13:52:08Z")

</div>

I am experimenting OpenCV’s integration with CUDA (`cv::cudacodec`) using the official example [here](https://github.com/opencv/opencv/blob/4.x/samples/gpu/video_writer.cpp). The sample code works. However, it seems to me that the resultant file generated by `cv::Ptr<cv::cudacodec::VideoWriter>` is an H264 file, without a proper container such as mp4/avi.

My question is whether or not there is a recommended way to wrap the h264 file (say in-memory?) into a proper mp4/avi file.

I can think of one circuitous approach to achieve this–apart from building OpenCV with `cv::cudacodec`, we firstly build FFmpeg with Nvidia Video codec and then build OpenCV with this particular FFmpeg build, then we use `cv::VideoWriter`’s FFmpeg backend to leverage hardware codec. But wondering if there is a more straightforward way…

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [August 21, 2023, 2:19pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/2 "2023-08-21T14:19:23Z")

</div>

for context:

> <https://stackoverflow.com/questions/76939818/how-to-convert-h264-file-to-mp4-with-opencv>

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [August 21, 2023, 2:29pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/4 "2023-08-21T14:29:20Z")

</div>

When I added `cudacodec::VideoWriter` back in I didn’t include container formats as I wasn’t sure if it was really necessary and I didn’t want to have to mess with `cv::VideoReader` to get to FFMpeg on the backend.

What is your use case for mp4?

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [August 21, 2023, 2:40pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/5 "2023-08-21T14:40:30Z")

</div>

lol you are also here

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [August 21, 2023, 2:41pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/6 "2023-08-21T14:41:05Z")

</div>

I want to resultant file to be directly played by 3rd-party media players.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [August 21, 2023, 5:43pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/7 "2023-08-21T17:43:01Z")

</div>

You can play .h264 in most media players if you don’t need to skip through the file.

The other option is to just use FFMpeg directly either by calling ffmpeg

```auto
ffmpeg -i input.h264 -c:v copy output.mp4

```

or using the libs to place it in a container.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [August 21, 2023, 8:30pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/8 "2023-08-21T20:30:47Z")

</div>

I guess the question could be:

How to feed GpuMats to a cv::VideoWriter initialized with HW\_ACCEL flags

I’m guessing that the source data resides in GpuMat instances, or at least `cv::UMat`

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [August 22, 2023, 5:15am UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/9 "2023-08-22T05:15:29Z")

</div>

> [@mamsds](#):
>
> I can think of one circuitous approach to achieve this–apart from building OpenCV with `cv::cudacodec`, we firstly build FFmpeg with Nvidia Video codec and then build OpenCV with this particular FFmpeg build, then we use `cv::VideoWriter`’s FFmpeg backend to leverage hardware codec. But wondering if there is a more straightforward way…

If your requirement for a container format is that strong then that would be a reasonable approach. Last time I checked writing a 1080p h264 file with `cv::cudacodec::VideoWriter` was neary twice (540fps vs 260fps) as fast as `cv::VideoWriter` with hardware acceleration.

The main use cases for `cv::cudacodec::VideoWriter` would be

1. when your data is already on the device, maybe your reading video with `cv::cudacodec::VideoReader`,
2. when you require maximum encoding performance (not that common, 540 fps is probably not that important to most people when the rest of their pipeline can only processing images at say 20 fps),
3. when you want to lower the processing overhead on the CPU (cv::VideoWriter with hardware accel still stresses the CPU).

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [August 22, 2023, 1:55pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/11 "2023-08-22T13:55:37Z")

</div>

Yes I am currently using this approach (`cv::VideoWriter` with hardware-accelerated FFmpeg backend) but I am exploring any better ways to achieve the same with better performance.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [August 22, 2023, 2:41pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/12 "2023-08-22T14:41:13Z")

</div>

Which media player are you using which can’t play raw h264?

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [August 23, 2023, 3:05pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/13 "2023-08-23T15:05:33Z")

</div>

I tested a few players.  
Windows Media Player and Windows 11’s “Photos” can’t play .h264 file.  
Also, VLC can only play the file if the extension if “.h264”. If I set the extension to “mp4”, VLC doesn’t work either.

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [August 23, 2023, 3:10pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/14 "2023-08-23T15:10:30Z")

</div>

This is what I can achieve, but still figuring if I can avoid using the FFmpeg backend altogether–invoking FFmpeg, even with hardware acceleration enabled, uses much more CPU (~2x-3x) than just using `cv::cudacodec::VideoWriter`.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [August 23, 2023, 3:22pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/15 "2023-08-23T15:22:05Z")

</div>

> [@mamsds](#):
>
> Also, VLC can only play the file if the extension if “.h264”. If I set the extension to “mp4”, VLC doesn’t work either.

That makes sense as its a h264 file not an mp4 container.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [August 23, 2023, 4:27pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/16 "2023-08-23T16:27:00Z")

</div>

> [@cudawarped](#):
>
> its a h264 file not an mp4 container.

right. it’s a bare video stream, a bitstream. it’s not a stream in a container.

no regular video player expects bare bitstreams. a container is required.

OpenCV only has its own code for reading/writing AVI containers. those are outdated.

if you want an actual MP4 media file, you need _something_ to write the stream(s) into such a container.

ffmpeg is that.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [August 23, 2023, 6:07pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/17 "2023-08-23T18:07:22Z")

</div>

> [@crackwitz](#):
>
> no regular video player expects bare bitstreams. a container is required.

VLC plays them just fine (if it has a .h264 extension it expects a h264 file, expecting it to play a raw h264 file with an mp4 extension as @mamsds did is asking a little too much), you just can’t seek effectively as there is no index.

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [August 24, 2023, 3:10pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/18 "2023-08-24T15:10:03Z")

</div>

and I tested one more important tool–Firefox cant play it.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [October 26, 2023, 5:10pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/19 "2023-10-26T17:10:10Z")

</div>

@mamsds This functionality has now been added to `cudacodec::VideoWriter`.

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [November 6, 2023, 4:05pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/20 "2023-11-06T16:05:42Z")

</div>

@cudawarped can you elaborate a bit? Like sharing a PR url or a new doc here?

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [November 6, 2023, 4:07pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/21 "2023-11-06T16:07:17Z")

</div>

[`cudacodec::VideoWriter` add container output by cudawarped · Pull Request #3569 · opencv/opencv\_contrib · GitHub](https://github.com/opencv/opencv_contrib/pull/3569) merged on Nov 2nd.

---

<div class="post-metadata">

**Author:** ![mamsds](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mamsds](https://forum.opencv.org/u/mamsds)\
**Post date:** [November 20, 2023, 4:27pm UTC](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313/22 "2023-11-20T16:27:32Z")

</div>

Hi @cudawarped ,

I just took a look at the PR you shared and I am about to try the new functionality, great job!

One question tho: I am aware that currently the code is in branch 4.x, but not in tag 4.8.1 (which is currently the latest tag), does it mean it is yet to be officially “released”? Or put it another way, is it the case that the code will be in the next release, probably 4.8.2?

Thanks,

[Next page](https://forum.opencv.org/t/convert-h264-file-to-mp4-with-cv-cudacodec/14313.md?page=2)
