ExoPlayer icon indicating copy to clipboard operation
ExoPlayer copied to clipboard

Implement an FfmpegVideoRenderer

Open EE-GSlomin opened this issue 8 years ago • 33 comments

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?

EE-GSlomin avatar Dec 05 '16 23:12 EE-GSlomin

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.

ojw28 avatar Dec 05 '16 23:12 ojw28

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?

EE-GSlomin avatar Dec 06 '16 00:12 EE-GSlomin

  • 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.

andrewlewis avatar Dec 06 '16 09:12 andrewlewis

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.

EE-GSlomin avatar Dec 06 '16 17:12 EE-GSlomin

It would be great to have a ffmpeg video render

michalliu avatar Feb 14 '17 07:02 michalliu

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

EE-GSlomin avatar Feb 14 '17 07:02 EE-GSlomin

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 avatar Jun 01 '17 21:06 goffioul

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 avatar Jun 01 '17 23:06 goffioul

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.

goffioul avatar Jun 02 '17 03:06 goffioul

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

ojw28 avatar Jun 02 '17 11:06 ojw28

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.

goffioul avatar Jun 05 '17 19:06 goffioul

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

michalliu avatar Jun 13 '17 03:06 michalliu

@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

goffioul avatar Jun 14 '17 23:06 goffioul

@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 avatar Jun 15 '17 03:06 michalliu

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 avatar Dec 24 '18 09:12 michalliu

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

michalliu avatar Dec 24 '18 10:12 michalliu

@michalliu how to use this ?

ranakhizar1556 avatar Dec 31 '18 05:12 ranakhizar1556

@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;
    }

michalliu avatar Jan 02 '19 02:01 michalliu

strongly suggest support FfmpegAudioRenderer,because lots of device are not work perfectly on MediaCode。

hubaoyu avatar Jul 03 '19 11:07 hubaoyu

There is a prototype pull request here: https://github.com/google/ExoPlayer/pull/7079

ojw28 avatar Mar 16 '20 20:03 ojw28

As an update on where we are with this:

  1. https://github.com/google/ExoPlayer/pull/7132 does most of the work required to add support. We're also merging some related changes (as you can see above!), and have some more to come (e.g., modifying DecoderInputBuffer to support extra padding which is a requirement for some FFmpeg decoders).
  2. For adaptive resolution switching, we have some internal changes that get this working for H.264 via a somewhat inefficient path. The efficient path appears to be broken in FFmpeg currently, and for that we've sent a patch to FFmpeg, which will hopefully be accepted (the patch can be found here).
  3. Use of the patch above with H.265 appears to sporadically native crash for me, and I haven't figured out what's wrong yet.

We will be working on getting more of this merged over the next couple of weeks.

ojw28 avatar May 11 '20 10:05 ojw28

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.

josephusmv avatar Sep 02 '20 14:09 josephusmv

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.

ojw28 avatar Sep 02 '20 14:09 ojw28

any updates here?

volser avatar Feb 21 '21 09:02 volser

any updates here?

ghost avatar Apr 03 '21 13:04 ghost

any updates here?

trycatchx avatar Jun 03 '21 07:06 trycatchx

The FfmpegVideoRenderer has be deleted in vesion 2.15.0 . Will you support it in the future? I need video soft decoder of H264 .

arlimm318 avatar Nov 03 '21 11:11 arlimm318

It has never been released in a stable release because it's not finished yet. It's only ever on the dev-v2 branch (i.e., under development).

We hope to be able to support it at some point in the future, but we do not have an estimated time. It's unlikely to be prioritized by the core team any time soon. The various updates above already document where we got to.

ojw28 avatar Nov 03 '21 11:11 ojw28

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

ojw28 avatar Mar 30 '22 16:03 ojw28

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 avatar Jan 15 '23 18:01 AhmedHumk