1. KokoseiJ

    OP KokoseiJ GBAtemp VOCALOID Enthusiast
    Member

    Joined:
    Jul 18, 2020
    Messages:
    307
    Country:
    Korea, South
    So I've been trying to make a video player that plays video from the server, right now I wrote a simple code to play a video from the SD card.
    but when it calls `avformat_find_stream_info()` It crashes, I can't seem to find any solutions about this and since I'm pretty new to C I don't have any idea about how to debug this.

    I'm not sure what to provide, so I'll just upload my source files:
    https://drive.google.com/file/d/1d3KAiimB_NMYpRa_kYzLXwi507tWygBJ/view?usp=sharing

    `3dsconf_default` is configure script I used to compile FFMPEG. FFMPEG version is 4.3.
    crash_dump_00000006.dmp file is a dump from a crash, I'm not sure what to do with this. GDB doesn't recognize this.
    Openico3DS.3dsx file is the one I sent to my 3DS. I sent it via 3DSlink, if that helps.
    I added a code that waits until user presses A before the code which causes the exception, so You'll have to press A to see exception.
    You'll have to put nico.mp4 file to `/ts/nico.mp4` in your SD card to replicate the issue. I haven't checked other video type, but mp4 is the one I will use so I have to debug in this format.

    If you're experienced at this kind of thing, please help me. It is so frustrating that I have no idea about what's going on, I can't even attempt to debug it.

    EDIT: Here's the crash screen.
    [​IMG]
    Stack dump is empty.
     
    Last edited by KokoseiJ, Jul 23, 2020
    Core_2_Extreme likes this.
  2. Core_2_Extreme

    Core_2_Extreme Advanced Member
    Newcomer

    Joined:
    Feb 11, 2019
    Messages:
    80
    Country:
    Japan
    hi, I have same error but I DELETED avformat_find_stream_info() from your code and tried.
    It won't crash and I got file info so I think we don't have to call avformat_find_stream_info().
    00000006.png

    However, I have other problem.
    When I call avcodec_send_packet() it returned -1094995529 (0xBEBBB1B7 : Invalid data found when processing input).
    Is there any idea?
    (I also tried your "nico.mp4" .)
    00000030.png


    Here is my code.
    Code:
     
    extern "C" {
    #include <libavcodec/avcodec.h>
    //#include <libavutil/mathematics.h>
    #include <libavutil/pixdesc.h>
    #include <libavformat/avformat.h>
    //#include <libswscale/swscale.h>
    //#include <libavutil/imgutils.h>
    }
    
               std::string file = "/test.mp4";
                int ffmpeg_result = 0;
                int video_stream_num = 0;
                AVCodecContext *context = NULL;
                AVFrame *raw_image = NULL;
                AVPacket *packet = NULL;
                AVCodec *codec = NULL;
                AVFormatContext* format_context = NULL;
    
                //alloc memory
                //Log_log_save() is my logging api you can use printf() insted.
                format_context = avformat_alloc_context();
                packet = av_packet_alloc();
                raw_image = av_frame_alloc();
                if(!format_context || !packet || !raw_image)
                    Log_log_save("debug", "alloc failed ", -1, false);
                else
                    Log_log_save("debug", "alloc ok ", 0, false);
    
                //open file
                ffmpeg_result = avformat_open_input(&format_context, file.c_str(), NULL, NULL);
                if(ffmpeg_result != 0)
                    Log_log_save("debug", "avformat_open_input() failed ", -1, false);
                else
                    Log_log_save("debug", "avformat_open_input() ok ", 0, false);
    
                //search video stream
                for(int i = 0; i < (int)format_context->nb_streams; i++)
                {
                    if (format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
                    {
                        video_stream_num = i;
                        break;
                    }
                }
    
                Log_log_save("debug", "video stream " + std::to_string(video_stream_num) + " ", 0, false);
    
                //find decoder
                codec = avcodec_find_decoder(format_context->streams[video_stream_num]->codecpar->codec_id);
                if(!codec)
                    Log_log_save("debug", "avcodec_find_decoder() failed ", -1, false);
                else
                    Log_log_save("debug", "avcodec_find_decoder() ok ", 0, false);
    
                //alloc memory
                context = avcodec_alloc_context3(codec);
                if(!context)
                    Log_log_save("debug", "alloc failed ", -1, false);
                else
                    Log_log_save("debug", "alloc ok ", 0, false);
    
                //open codec
                ffmpeg_result = avcodec_open2(context, codec, NULL);
                if(ffmpeg_result != 0)
                    Log_log_save("debug", "avcodec_open2() failed ", ffmpeg_result, false);
                else
                    Log_log_save("debug", "avcodec_open2() ok ", ffmpeg_result, false);
    
                while(true)
                {
                    //read 1 frame
                    ffmpeg_result = av_read_frame(format_context, packet);
                    if(ffmpeg_result != 0)
                        Log_log_save("debug", "av_read_frame() failed ", ffmpeg_result, false);
                    else
                        Log_log_save("debug", "av_read_frame() ok ", ffmpeg_result, false);
    
                    Log_log_save("debug", "frame size " + std::to_string(packet->size) + " ", 0, false);
    
                    if(packet->stream_index == format_context->streams[video_stream_num]->index) //if frame was video data
                    {
                        Log_log_save("debug", "video frame ", 0, false);
    
                        ffmpeg_result = avcodec_send_packet(context, packet);
                        if(ffmpeg_result != 0)
                            Log_log_save("debug", "avcodec_send_packet() failed ", ffmpeg_result, false);
                        else
                            Log_log_save("debug", "avcodec_send_packet() ok ", ffmpeg_result, false);
    
                        ffmpeg_result = avcodec_receive_frame(context, raw_image);
                        if(ffmpeg_result != 0)
                            Log_log_save("debug", "avcodec_receive_frame() failed ", ffmpeg_result, false);
                        else
                            Log_log_save("debug", "avcodec_receive_frame() ok ", ffmpeg_result, false);
    
                        Log_log_save("debug", "w " + std::to_string(raw_image->width) + " h " + std::to_string(raw_image->height) + " format " + av_get_pix_fmt_name((AVPixelFormat)raw_image->format), 1234567890, false);
    
                        break;
                    }
                    else
                        Log_log_save("debug", "other frame retrying... ", 0, false);
                }
     
    KokoseiJ likes this.
  3. KokoseiJ

    OP KokoseiJ GBAtemp VOCALOID Enthusiast
    Member

    Joined:
    Jul 18, 2020
    Messages:
    307
    Country:
    Korea, South
    Wow, thanks!

    I wasn't able to visit forum for a while, sorry for the late reply.

    I currently don't have lots of time on my hand, I could revisit it after 2 weeks at best. but when I do it, I'll make sure to notify you.

    Thanks a lot again!
     
    Core_2_Extreme likes this.
  4. Core_2_Extreme

    Core_2_Extreme Advanced Member
    Newcomer

    Joined:
    Feb 11, 2019
    Messages:
    80
    Country:
    Japan
    After that I found we need to call avcodec_parameters_to_context() and we need to run these code on another thread or it WILL CRASH.
    I don't know why but I created another thread using threadCreate() and tried decoding, it worked fine.
    00000006.png


    Here is my code.
    Code:
       
    void Test_thread(void* args)
    {
        std::string file = "/test.mp4";
        int ffmpeg_result = 0;
        int video_stream_num = 0;
        AVCodecContext *context = NULL;
        AVFrame *raw_image = NULL;
        AVPacket *packet = NULL;
        AVCodec *codec = NULL;
        AVFormatContext* format_context = NULL;
    
        //alloc memory
        //Log_log_save() is my logging api you can use printf() insted.
        format_context = avformat_alloc_context();
        packet = av_packet_alloc();
        raw_image = av_frame_alloc();
        if(!format_context || !packet || !raw_image)
                Log_log_save("debug", "alloc failed ", -1, false);
        else
                Log_log_save("debug", "alloc ok ", 0, false);
    
        //open file
        ffmpeg_result = avformat_open_input(&format_context, file.c_str(), NULL, NULL);
        if(ffmpeg_result != 0)
                Log_log_save("debug", "avformat_open_input() failed ", -1, false);
        else
                Log_log_save("debug", "avformat_open_input() ok ", 0, false);
    
        //search video stream
        for(int i = 0; i < (int)format_context->nb_streams; i++)
        {
                if (format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
                {
                        video_stream_num = i;
                        break;
                }
        }
    
        Log_log_save("debug", "video stream " + std::to_string(video_stream_num) + " ", 0, false);
    
        //find decoder
        codec = avcodec_find_decoder(format_context->streams[video_stream_num]->codecpar->codec_id);
        if(!codec)
                Log_log_save("debug", "avcodec_find_decoder() failed ", -1, false);
        else
                Log_log_save("debug", "avcodec_find_decoder() ok ", 0, false);
    
        //alloc memory
        context = avcodec_alloc_context3(codec);
        if(!context)
                Log_log_save("debug", "alloc failed ", -1, false);
        else
                Log_log_save("debug", "alloc ok ", 0, false);
    
        ffmpeg_result = avcodec_parameters_to_context(context, format_context->streams[video_stream_num]->codecpar);
        if(ffmpeg_result == 0)
            Log_log_save("debug", "avcodec_parameters_to_context() ok ", ffmpeg_result, false);
        else
            Log_log_save("debug", "avcodec_parameters_to_context() failed ", ffmpeg_result, false);
    
        //open codec
        ffmpeg_result = avcodec_open2(context, codec, NULL);
        if(ffmpeg_result != 0)
                Log_log_save("debug", "avcodec_open2() failed ", ffmpeg_result, false);
        else
                Log_log_save("debug", "avcodec_open2() ok ", ffmpeg_result, false);
    
        while(true)
        {
                //read 1 frame
                ffmpeg_result = av_read_frame(format_context, packet);
                if(ffmpeg_result != 0)
                        Log_log_save("debug", "av_read_frame() failed ", ffmpeg_result, false);
                else
                        Log_log_save("debug", "av_read_frame() ok ", ffmpeg_result, false);
    
                Log_log_save("debug", "frame size " + std::to_string(packet->size) + " ", 0, false);
    
                if(packet->stream_index == format_context->streams[video_stream_num]->index) //if frame was video data
                {
                        Log_log_save("debug", "video frame ", 0, false);
    
                        ffmpeg_result = avcodec_send_packet(context, packet);
                        if(ffmpeg_result != 0)
                                Log_log_save("debug", "avcodec_send_packet() failed ", ffmpeg_result, false);
                        else
                                Log_log_save("debug", "avcodec_send_packet() ok ", ffmpeg_result, false);
    
                        ffmpeg_result = avcodec_receive_frame(context, raw_image);
                        if(ffmpeg_result != 0)
                                Log_log_save("debug", "avcodec_receive_frame() failed ", ffmpeg_result, false);
                        else
                                Log_log_save("debug", "avcodec_receive_frame() ok ", ffmpeg_result, false);
    
            //      Log_log_save("debug", "w " + std::to_string(raw_image->width) + " h " + std::to_string(raw_image->height) + " format " + av_get_pix_fmt_name((AVPixelFormat)raw_image->format), 1234567890, false);
    
                        break;
                }
                else
                        Log_log_save("debug", "other frame retrying... ", 0, false);
        }
    }
    
    //call this from main thread.
    #define STACKSIZE (64 * 1024)
    Thread thread_context;
    thread_context = threadCreate(Test_thread, (void*)(""), STACKSIZE, 0x23, -1, false);
    
    
    If you have any questions let me know.
     
    KokoseiJ likes this.
  5. KokoseiJ

    OP KokoseiJ GBAtemp VOCALOID Enthusiast
    Member

    Joined:
    Jul 18, 2020
    Messages:
    307
    Country:
    Korea, South
    Absolutely stunning. I didn't expect you to investigate further.

    I know that I'm really, really late- But I really appreciate your help, and all the times you spent investigating this error.

    Thank you so much, kind stranger! I'll be sure to alert you when I make more progress.
     
    Core_2_Extreme likes this.
Draft saved Draft deleted
Loading...

Hide similar threads Similar threads with keywords - avformat_find_stream_info, running, crashes