Q. FFMPEG - linux (Rasberry pi 4- Raspbian)- ошибка FFMPEG av_read_frame

Пользовательская среда

-Raspberry Pi 4B 4G x2

-arm32 и arm64

-OS: Распбиан

-gcc (Raspbian 8.3.0-6+rpi1) 8.3.0

-ffmpeg версии 4.1.4-1+rpt7~deb10u1, созданный с помощью gcc 8 (Raspbian 8.3.0-6+rpi1)

-IDE-visual studio 2017-соединение ssh

Доброе утро. У меня есть вопрос, опубликую его.

При установке Raspbian используется установленная библиотека FFMPEG.

Я хочу вывести видеодисплей - файл, закодированный в h264 с использованием gtk3.0.

Когда я открываю видеофайл, нахожу кодек и пытаюсь прочитать кадр, я получаю сообщение об ошибке и спрашиваю.

  1. Заполнение структурной памяти AVPacket? ошибка

2. Ошибка AVPacket-data: невозможно получить доступ к памяти по адресу 0xxxxxxxxxxxx>

  1. Ошибка значения AVPacket-stream_index. Значения stream_index и flags, по-видимому, поменялись местами.

мой исходный код и фотографии ошибок прилагаются. Спасибо.

case 1 ошибка stream_index (значение флагов ->stream_index)

введите описание изображения здесь

случай 2 ошибка доступа к памяти данных

введите описание изображения здесь

typedef struct _struMovContext2
{
AVFormatContext*    pFormatCtx;
AVCodecContext*     pVCodecCtx;
AVCodecContext*     pACodecCtx;
AVCodec*            pVCodec;
AVCodec*            pACodec;
int                 nVStreamIndex;
int                 nAStreamIndex;
struct SwsContext*  pSwsCtx;
GtkWidget*          pImage;
pthread_t           tID;    
}MovContext2;

static MovContext2      Ctx;

static void pixmap_destroy_nf(guchar *pixels, gpointer data)
{
    printf("Destroy pixmap - not sure how\n");
}

static void* PlayBackGround(void* pData)
{
MovContext2*    pCtx = NULL;
GdkPixbuf*      pixbuf = NULL;
GError*         error = NULL;   
int             nFrameWidth, nFrameHeight;
int             nFrameEos = 0;
AVFrame*        pFrame = NULL;
AVFrame*        pPicture_RGB = NULL;
AVPacket        packet;
uint8_t*        pBuffer = NULL;

cairo_surface_t*    surface = NULL;
cairo_t*            cr = NULL;

//if ((pCtx = static_cast<MovContext2*>(pData)) == NULL)
pCtx = &Ctx;
if(pCtx == NULL)
{
    av_log(NULL, AV_LOG_ERROR, "Couldn't get context struct - Data nullpointer");
    return NULL;
}

printf("In Thread - PlayBackGround\n");


if ((pFrame = av_frame_alloc()) == NULL)
{
    av_log(NULL, AV_LOG_ERROR, "Couldn't alloc frame");
    return NULL;
}

if ((pPicture_RGB = av_frame_alloc()) == NULL)
{
    av_log(NULL, AV_LOG_ERROR, "Couldn't alloc Picture RGB");
    return NULL;
}

if ((pBuffer = (uint8_t*)malloc(avpicture_get_size(AV_PIX_FMT_RGB24, 1920, 1080))) == NULL)
{
    av_log(NULL, AV_LOG_ERROR, "Couldn't malloc data buffer");
    return NULL;
}
avpicture_fill((AVPicture*)pPicture_RGB, pBuffer, AV_PIX_FMT_RGB24, 1920, 1080);*/

av_init_packet(&packet);    
packet.data = NULL;
packet.size = 0;

//packet = *av_packet_alloc();

while (av_read_frame(pCtx->pFormatCtx, &packet) >= 0)
{
    printf("Read packet stream index : %d\n", packet.stream_index);

    if (packet.stream_index == pCtx->nVStreamIndex)
    {
        //av_usleep(33670);

        printf("Decoding to frame start\n");
        if (avcodec_decode_video2(pCtx->pVCodecCtx, pFrame, &nFrameEos, &packet) < 0)
        {
            av_log(NULL, AV_LOG_ERROR, "Decod video error");
            return NULL;
        }
        printf("Decoding to frame end\n");

        nFrameWidth = pCtx->pVCodecCtx->width;
        nFrameHeight = pCtx->pVCodecCtx->height;

        printf("frame Width : %d, Height : %d\n", nFrameWidth, nFrameHeight);

        pCtx->pSwsCtx = sws_getContext(nFrameWidth,
            nFrameHeight,
            pCtx->pVCodecCtx->pix_fmt,
            nFrameWidth,
            nFrameHeight,
            AV_PIX_FMT_RGB24,
            SWS_BICUBIC,
            NULL, NULL, NULL);

        printf("sws Get context\n");

        if (nFrameEos > 0)
        {
            sws_scale(  pCtx->pSwsCtx,
                        pFrame->data,
                        pFrame->linesize,
                        0,
                        nFrameHeight,
                        pPicture_RGB->data,
                        pPicture_RGB->linesize);

            printf("sws set scale\n");

            pixbuf = gdk_pixbuf_new_from_data(pPicture_RGB->data[0],
                GDK_COLORSPACE_RGB,
                0,
                8,
                nFrameWidth,
                nFrameHeight,
                pPicture_RGB->linesize[0],
                pixmap_destroy_nf,
                NULL);

            printf("create pixbuf from frame data\n");

            gtk_image_set_from_pixbuf((GtkImage*)pCtx->pImage, pixbuf);

            g_object_unref(pixbuf);
            cairo_surface_destroy(surface);
            cairo_destroy(cr);

            //gdk_threads_leave();

        }
        av_free_packet(&packet);
    }
}


printf("Exit Thread\n");

return NULL;
}


int main(int argc, char *argv[])
{
GtkWidget*          overlay;
GtkWidget*          eventBox;
GError*             err = NULL;
CMonitorManager*    pManager;
GdkRectangle        Rect;
char*               pFileURI = "/home/pi/test.mp4";
//char*             pFileURI = "/home/ubuntu/test.mp4";
//char*             pFileURI = "/home/ubuntu/cev.avi";
int                 nIndex;
//MovContext2           Ctx;

//XInitThreads();   
memset(&Ctx, 0x00, sizeof(Ctx));
av_register_all();

if (avformat_open_input(&Ctx.pFormatCtx, pFileURI, NULL, NULL) != 0)
{
    av_log(NULL, AV_LOG_ERROR, "Couldn't open file");
    return FALSE;
}
printf("C - open uri\n");

if (avformat_find_stream_info(Ctx.pFormatCtx, NULL) != 0)
{
    av_log(NULL, AV_LOG_ERROR, "Couldn't find stream information");
    return FALSE;
}
printf("C - find stream info\n");

av_dump_format(Ctx.pFormatCtx, 0, pFileURI, 0);
printf("C - media dump\n");

Ctx.nVStreamIndex = av_find_best_stream(Ctx.pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (Ctx.nVStreamIndex == AVERROR_STREAM_NOT_FOUND)
{
    for (nIndex = 0; nIndex < Ctx.pFormatCtx->nb_streams; nIndex++)
    {
        if (Ctx.pFormatCtx->streams[nIndex]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            Ctx.nVStreamIndex = nIndex;
            break;
        }
    }

    if (Ctx.nVStreamIndex < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "Didn't find a video stream");
        return FALSE;
    }
}
printf("C - get video stream index\n");

Ctx.nAStreamIndex = av_find_best_stream(Ctx.pFormatCtx, AVMEDIA_TYPE_AUDIO, Ctx.nVStreamIndex, -1, NULL, 0);
if (Ctx.nAStreamIndex == AVERROR_STREAM_NOT_FOUND)
{
    for (nIndex = 0; nIndex < Ctx.pFormatCtx->nb_streams; nIndex++)
    {
        if (Ctx.pFormatCtx->streams[nIndex]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
        {
            Ctx.nAStreamIndex = nIndex;
            break;
        }
    }

    if (Ctx.nAStreamIndex < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "Didn't find a audio stream");
    }
}
printf("C - get audio stream index\n");

if ((Ctx.pFormatCtx->streams[Ctx.nVStreamIndex]->codecpar = avcodec_parameters_alloc()) == NULL)
{
    av_log(NULL, AV_LOG_ERROR, "Couldn't alloc video codec parameters");
    return FALSE;
}
avcodec_parameters_from_context(Ctx.pFormatCtx->streams[Ctx.nVStreamIndex]->codecpar,
    Ctx.pFormatCtx->streams[Ctx.nVStreamIndex]->codec);
printf("C - video codec parameter alloc\n");


Ctx.pVCodec = avcodec_find_decoder(Ctx.pFormatCtx->streams[Ctx.nVStreamIndex]->codecpar->codec_id);
printf("C - find video codec %s \n", Ctx.pVCodec->long_name);
Ctx.pVCodecCtx = avcodec_alloc_context3(Ctx.pVCodec);

avcodec_parameters_to_context(Ctx.pVCodecCtx, Ctx.pFormatCtx->streams[Ctx.nVStreamIndex]->codecpar);

if (avcodec_open2(Ctx.pVCodecCtx, Ctx.pVCodec, NULL) < 0)
{
    av_log(NULL, AV_LOG_ERROR, "Could not open video codec");
    return FALSE;
}
printf("C - video codec context oepn\n");

if (Ctx.nAStreamIndex > 0)
{
    if ((Ctx.pFormatCtx->streams[Ctx.nAStreamIndex]->codecpar = avcodec_parameters_alloc()) != NULL)
    {
        avcodec_parameters_from_context(Ctx.pFormatCtx->streams[Ctx.nAStreamIndex]->codecpar,
            Ctx.pFormatCtx->streams[Ctx.nAStreamIndex]->codec);
        printf("C - audio codec parameter alloc\n");

        Ctx.pACodec = avcodec_find_decoder(Ctx.pFormatCtx->streams[Ctx.nAStreamIndex]->codecpar->codec_id);
        printf("C - find audio codec\n");
        Ctx.pACodecCtx = avcodec_alloc_context3(Ctx.pACodec);

        if (avcodec_open2(Ctx.pACodecCtx, Ctx.pACodec, NULL) < 0) {
            av_log(NULL, AV_LOG_ERROR, "Could not open audio codec");
        }
        printf("C - audio codec context oepn\n");
    }
    else
    {
        av_log(NULL, AV_LOG_ERROR, "Couldn't alloc video codec parameters");
    }
}

Ctx.pVCodecCtx->width = 1920;
Ctx.pVCodecCtx->height = 1080;

Ctx.pSwsCtx = sws_getContext(Ctx.pVCodecCtx->width,
    Ctx.pVCodecCtx->height,
    Ctx.pVCodecCtx->pix_fmt,
    Ctx.pVCodecCtx->width,
    Ctx.pVCodecCtx->height,
    AV_PIX_FMT_YUV420P,
    SWS_BILINEAR,
    NULL,
    NULL,
    NULL);

pthread_create(&Ctx.tID, NULL, PlayBackGround, &Ctx);

GtkWidget *window;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

Ctx.pImage = gtk_image_new();
gtk_container_add(GTK_CONTAINER(window), Ctx.pImage);

gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 1920, 1080);
gtk_widget_show_all(window);

gtk_main();

return 0;
}

0 ответов

Другие вопросы по тегам