Search code examples
androidffmpegstreamingrtsp

Too small ffmpeg rtsp decoding buffer


I'm decoding rtsp on Android with ffmpeg, and I quickly see pixelization when the image updates quickly or with a high resolution:

working decoded frame

non working decoded frame

After googling, I found that it might be correlated to the UDP buffer size. I have then recompiled the ffmpeg library with the following parameters inside ffmpeg/libavformat/udp.c

#define UDP_TX_BUF_SIZE 327680
#define UDP_MAX_PKT_SIZE 655360

It seems to improve but it still starts to fail at some point. Any idea which buffer I should increase and how?


Solution

  • For my problem (http://libav-users.943685.n4.nabble.com/UDP-Stream-Read-Pixelation-Macroblock-Corruption-td4655270.html), I was trying to capture from a multicast UDP stream that had been set-up by someone else. Because I didn't have the ability to mess with the source, I ended up switching from using libav to using libvlc as a wrapper and it worked perfectly. Here is the summary of what worked for me:

    stream.h:

    #include <vlc/vlc.h>
    #include <vlc/libvlc.h>
    
    struct ctx {
       uchar* frame;
    };
    

    stream.cpp:

    void* lock(void* data, void** p_pixels){
      struct ctx* ctx = (struct ctx*)data;
      *p_pixels = ctx->frame;
      return NULL;
    }
    
    void unlock(void* data, void* id, void* const* p_pixels){
      struct ctx* ctx = (struct ctx*)data;
      uchar* pixels = (uchar*)*p_pixels;
      assert(id == NULL);
    }
    

    main.cpp:

    struct ctx* context = (struct ctx*)malloc(sizeof(*context));
    const char* const vlc_args[] = {"-vvv",
                                     "-q",
                                     "--no-audio"};
    libvlc_media_t* media = NULL;
    libvlc_media_player_t* media_player = NULL;
    libvlc_instance_t* instance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
    
    media = libvlc_media_new_location(instance, "udp://@123.123.123.123:1000");
    media_player = libvlc_media_player_new(instance);
    libvlc_media_player_set_media(media_player, media);
    libvlc_media_release(media);
    context->frame = new uchar[height * width * 3];
    libvlc_video_set_callbacks(media_player, lock, unlock, NULL, context);
    libvlc_video_set_format(media_player, "RV24", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH * 3);
    libvlc_media_player_play(media_player);