Skip to content
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

Implement an FfmpegVideoRenderer #2159

Open
EE-GSlomin opened this issue Dec 5, 2016 · 33 comments
Open

Implement an FfmpegVideoRenderer #2159

EE-GSlomin opened this issue Dec 5, 2016 · 33 comments

Comments

@EE-GSlomin
Copy link
Contributor

I apologize for filing this as an "issue", unfortunately github doesn't provide too many avenues of communication.

I have considered writing my own FfmpegVideoRenderer (or perhaps using libx264 directly) to software decode unsupported formats for viewing on the phone. I was mostly curious if this has been attempted before, and dropped due to technical reasons or perhaps someone had already planned on working on it?

@ojw28 ojw28 changed the title Any plans for an FfmpegVideoRenderer? Implement an FfmpegVideoRenderer Dec 5, 2016
@ojw28
Copy link
Contributor

ojw28 commented Dec 5, 2016

We don't have any plans to provide an Ffmpeg video renderer. I'm fairly sure it's perfectly feasible to implement one, although note that in many cases software decoders will not be as power efficient or as performant as those provided by the platform. Marking as an enhancement in any case.

@EE-GSlomin
Copy link
Contributor Author

Appreciate the response. I'll definitely take a crack at this then. The idea was that it would only be used as a fallback.

There was one thing I wasn't 100% sure of though. Most cases of unsupported video in my use case is generally because of extreme resolutions (3-8MP cameras). Would it make more sense to scale the image using ffmpeg/x264? Or rely on the rasterizer to downscale the final result?

@andrewlewis
Copy link
Collaborator

  • Last time I checked, libx264 was only for encoding (not decoding) but FFmpeg does have an H.264/AVC decoder so it makes sense to wrap that. This would also give the option of using other codecs. Some parts of the existing ffmpeg audio extension could be reused.
  • The vp9 extension may be a useful starting point.
  • For scaling and color space conversion: it might be necessary to do some experiments to find out whether this is best done inside FFmpeg or separately on its output. In general, the decoder has to keep full-resolution frames in memory. The vp9 extension has code for doing color space conversion from YCbCr to RGB using GLES, rendering to a GLSurfaceView.

@EE-GSlomin
Copy link
Contributor Author

Yep you would be correct. I always assumed it supported decoding, but I never dug into the libx264 side of it too much until now.

Sounds like I'll have to do a bit of benchmarking to come up with the ideal solution. I will definitely look at the VP9 extension more. Thanks for the advice.

@michalliu
Copy link
Contributor

It would be great to have a ffmpeg video render

@EE-GSlomin
Copy link
Contributor Author

EE-GSlomin commented Feb 14, 2017

I ended up not pursuing this on my end because of the licensing issues with FFMPEG.

@goffioul
Copy link
Contributor

goffioul commented Jun 1, 2017

I've started writing a skeleton of FfmpegVideoRenderer. At the moment it's mainly a lot of placeholders with plumbing to a ffmpeg mpeg2video decoder. However the decoding fails in ffmpeg, because of invalid input data.

The "render" method is very similar to other available renderers: wait for input format, then drain output buffers, then feed input buffers. What I noticed is that the data returned by "readSource" (inherited from BaseRenderer) only contains the picture data (with start code 00000100), but I also need to feed all data to the ffmpeg decoder, in particular the sequence segment (with start code 000001b3). I have no idea why I only get the picture segments, and not the entire MPEG2 stream. Any hint appreciated.

@goffioul
Copy link
Contributor

goffioul commented Jun 1, 2017

I've compared the data that is processed by MediaCodecRender (my Android device has a MPEG2 decoder builtin), and it appears that its calls to "readSource" also only get the picture segments. Is that a property of the implementation of H262Reader? (my sample clip is a MPEG/TS with MPEG2/MP2). If yes, is there a workaround to make the renderer to get the full MPEG2 data stream?

@goffioul
Copy link
Contributor

goffioul commented Jun 2, 2017

My initial assessment was incorrect. The MPEG2 stream is segmented by H262Reader into TrackOutput on the START_PICTURE boundaries. That's why I see that start code when I inspect the starting bytes of the data received my renderer. However the problem is that the data between the start of the MPEG2 stream and the first START_PICTURE is lost and does not reach the renderer. And this is where the sequence header is located (the stream starts with sequence, extended sequence, GOP and then the first START_PICTURE), which is required by ffmpeg decoder.

@ojw28
Copy link
Contributor

ojw28 commented Jun 2, 2017

You'll probably find what you're looking for in the Format that's provided to the renderer. Specifically in Format.initializationData.

@goffioul
Copy link
Contributor

goffioul commented Jun 5, 2017

Thanks, I hadn't realized that the initialization data contained the sequence and sequence extension headers. They're pre-parsed by the mpeg2video codec automatically when set as extradata on the context. Now I can get my FfmpegVideoRenderer to work.

@michalliu
Copy link
Contributor

Hi @goffioul could you share you code regarding FfmpegVideoRenderer thanks. I'd like to implement the very same functionality.

@goffioul
Copy link
Contributor

@michalliu This is the current code I have. It's quite raw, it's just an experiment at the moment. It was focused on getting MPEG2 decoder, but unfortunately I hit bug #2891, in particular bad pixellation due to the segmentation in H262Reader. And trying to fix it resulted in another bug I don't know how to solve. A few things to note:

  • the target was live TV streams, that's why it has a deinterlace filter
  • you need to compile ffmpeg with the flags: --enable-swscale --enable-avfilter --enable-decoder=mpeg2video --enable-filter=yadif --enable-filter=scale (and you need to remove the flags --disable-swscale --disable-avfilter)

At the moment I stopped working on this, because of other priorities and a lack of time. But I hope to be able to resume the work at a later stage. Let me know if you're interested in joint effort.

ffmpeg-video-renderer.zip

@michalliu
Copy link
Contributor

michalliu commented Jun 15, 2017

@goffioul Thanks for sharing the code and the instructions. I'm very interested in this idea. My work is busy too. We use exoplayer in our project currently. Hopefully I can persuade my boss to support my idea so i can put my time on it.

@michalliu
Copy link
Contributor

Hi guys. I'd like to let you know we have implemented hevc software decoder using OpenHEVC, we are ready to submit a merge request soon.

@michalliu
Copy link
Contributor

The repository is located at https://github.com/michalliu/exoplayer2-hevc-extension

@ranakhizar1556
Copy link

@michalliu how to use this ?

@michalliu
Copy link
Contributor

michalliu commented Jan 2, 2019

@michalliu how to use this ?

@ranakhizar1556
same as the vpx render, add code to your render list. Noted, the adding sequence is important, if you just want debugging you should add LibHevcVideoRenderer firstly.

    protected List<Renderer> buildVideoRenderers() {
        List<Renderer> renderers = new ArrayList<>();
        renderers.add(new MediaCodecVideoRenderer(context, MediaCodecSelector.DEFAULT, allowedJoiningTimeMs, drmSessionManager, false, handler, videoRendererEventListener, droppedFrameNotificationAmount));
        renderers.add(new LibHevcVideoRenderer(true, allowedJoiningTimeMs, handler, videoRendererEventListener, droppedFrameNotificationAmount, null, false));
        renderers.add(new LibvpxVideoRenderer(true, allowedJoiningTimeMs, handler, videoRendererEventListener, droppedFrameNotificationAmount, null, false, true));
        return renderers;
    }

@hubaoyu

This comment has been minimized.

@ojw28
Copy link
Contributor

ojw28 commented Mar 16, 2020

There is a prototype pull request here: #7079

ojw28 added a commit that referenced this issue Mar 19, 2020
ojw28 added a commit that referenced this issue Mar 19, 2020
Issue: #2159
PiperOrigin-RevId: 301351495
ojw28 added a commit that referenced this issue Mar 19, 2020
The restriction that these classes only work with SimpleDecoders
is unnecessary. An FfmpegVideoRenderer will not be able to use a
SimpleDecoder, because the SimpleDecoder assumption that each input
buffer can be decoded immediately into a corresponding output is
not true for all video codecs that Ffmpeg supports (e.g., H264 does
not have this property). Generalizing SimpleDecoderVideoRenderer to
DecoderVideoRenderer will allow FfmpegVideoRenderer to still use
the base class, without having to use a SimpleDecoder.

This is a preliminary change toward being able to merge a version
of #7079.

Issue: #2159
PiperOrigin-RevId: 301412344
ojw28 added a commit that referenced this issue May 14, 2020
FFmpeg requires input buffers to be sized larger than the size
of the data they contain. This is to allow optimized decoder
implementations that read data in fixed size chunks, without
the risk of such decoders reading beyond the end of the buffer.

Issue: #2159
PiperOrigin-RevId: 310946866
@josephusmv
Copy link

Is there any updates for this request? I wish to try to do similar things now as the Exoplayer is not working in my target devices when playing 4K video(see my issue #7835 ). I understand that the HW decoder is far more powerful than SW's, but the fact is that:
in most cases, we have to use SW solution with Exoplayer as some kind of POC purpose before we actually integrates our staffs with customers' real HW. In other word, we wish our POC player is totally independent to any customer's HW.
So this requirement really has huge values for many users, at least, in my case it is values a lot.

@ojw28
Copy link
Contributor

ojw28 commented Sep 2, 2020

We haven't made much progress beyond the update above, unfortunately. Doing it properly turned out to be quite a lot of work. Since this issue isn't considered high priority, it's being worked on on a best-effort basis, and we haven't managed to dedicate sufficient time to get something merged. We have made a small amount of progress since the previous update above:

  1. Our FFmpeg patch got merged, which fixes H.264 adaptation without the need for hacks in ExoPlayer code.
  2. We root caused the sporadic H.265 crash. Unfortunately this didn't resolve the fact that adaptation doesn't work properly for H.265, which we've yet to root cause. We also haven't managed to get it working with AV1 yet.

@volser

This comment has been minimized.

2 similar comments
@ghost
Copy link

ghost commented Apr 3, 2021

any updates here?

@trycatchx
Copy link

any updates here?

@arlimm318

This comment has been minimized.

@ojw28

This comment has been minimized.

@ojw28
Copy link
Contributor

ojw28 commented Mar 30, 2022

Note for whoever picks this up next: Take a look at the comment here.

@AhmedHumk
Copy link

Note for whoever picks this up next: Take a look at the comment here.

this is an outdated wrapper also it requires a new aar to allow the ffmpeg decoders to work

@AhmedHumk
Copy link

this would be enough to be merged to the ffmpeg extenstion
https://github.com/AhmedHumk/ffmpegVideoDecoder

@anilbeesetti
Copy link

anilbeesetti commented Jul 20, 2023

checkout this library for the implementation of FfmpegVideoRenderer: https://github.com/anilbeesetti/nextlib
used in: https://github.com/anilbeesetti/nextplayer

@itsthe1-apps
Copy link

this would be enough to be merged to the ffmpeg extenstion https://github.com/AhmedHumk/ffmpegVideoDecoder

I was having difficulties to use the extension

@christosts christosts assigned rohitjoins and unassigned christosts Feb 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests