nyanmisaka / ffmpeg-rockchip

FFmpeg with async and zero-copy Rockchip MPP & RGA support
Other
325 stars 47 forks source link

Use `h264_rkmpp` decoder video to fast and Use `h264` is no issue. #32

Closed Coloryr closed 3 months ago

Coloryr commented 3 months ago

this is my code.

ffmpeg.avformat_open_input(&pFormatContext, url, null, null).ThrowExceptionIfError();
ffmpeg.avformat_find_stream_info(_pFormatContext, null).ThrowExceptionIfError();

_streamIndex = ffmpeg.av_find_best_stream(_pFormatContext,
    AVMediaType.AVMEDIA_TYPE_VIDEO, -1, -1, null, 0);
AVCodec* codec;

if (_streamIndex >= 0)
{
    codec = ffmpeg.avcodec_find_decoder_by_name("h264_rkmpp");
    if (codec != null)
    {
        Console.WriteLine("Using rkmpp for decoding\n");
        _videoCodecContext = ffmpeg.avcodec_alloc_context3(codec);
        ffmpeg.avcodec_parameters_to_context(_videoCodecContext,
            _pFormatContext->streams[_streamIndex]->codecpar)
            .ThrowExceptionIfError();
        ffmpeg.avcodec_open2(_videoCodecContext, codec, null).ThrowExceptionIfError();
    }
    else
    {
        codec = ffmpeg.avcodec_find_decoder_by_name("h264");
        Console.WriteLine("rkmpp decoder not found\n");
        _videoCodecContext = ffmpeg.avcodec_alloc_context3(codec);
        ffmpeg.avcodec_parameters_to_context(_videoCodecContext,
            _pFormatContext->streams[_streamIndex]->codecpar)
            .ThrowExceptionIfError();
        ffmpeg.avcodec_open2(_videoCodecContext, codec, null).ThrowExceptionIfError();
    }
do
{
    ffmpeg.av_packet_unref(_pPacket);
    error = ffmpeg.av_read_frame(_pFormatContext, _pPacket);

    if (error == ffmpeg.AVERROR_EOF || cancellationToken.IsCancellationRequested)
    {
        return;
    }

    error.ThrowExceptionIfError();
if (_pPacket->stream_index == _streamIndex)
                {
                    ffmpeg.avcodec_send_packet(_videoCodecContext, _pPacket)
                        .ThrowExceptionIfError();
                    error = ffmpeg.avcodec_receive_frame(_videoCodecContext, _videoFrame);
                    if (error == 0)
                    {
                        AVFrame frame;
                        //if (_videoCodecContext->hw_device_ctx != null)
                        //{
                        //    if (HWDevice == (AVHWDeviceType)12)
                        //    {
                        //        _receivedFrame->format = (int)AVPixelFormat.AV_PIX_FMT_NV12;

                        //        _receivedFrame->width = _videoFrame->width;
                        //        _receivedFrame->height = _videoFrame->height;
                        //    }
                        //    ffmpeg.av_hwframe_transfer_data(_receivedFrame, _videoFrame, 0)
                        //        .ThrowExceptionIfError();
                        //    frame = *_receivedFrame;
                        //}
                        //else
                            frame = *_videoFrame;

                        var convertedFrame = vfc.Convert(frame);
                        IPHostApi.SetVideoPtr(uuid, convertedFrame.width, convertedFrame.height, (IntPtr)convertedFrame.data[0]);
                    }
                    else if (error != -11)
                    {
                        error.ThrowExceptionIfError();
                    }

The playback speed is like 1.5 times

Coloryr commented 3 months ago

use ffplay test play is ok.

nyanmisaka commented 3 months ago

I can't reproduce the problem. You need to set the timestamp and time_base correctly to get the correct playback speed.

Coloryr commented 3 months ago

Use time_base was solved this issue