User environment
-Raspberry Pi 4B 4G x2
-arm32 & arm64
-OS: Raspbian
-gcc (Raspbian 8.3.0-6+rpi1) 8.3.0
-ffmpeg version 4.1.4-1+rpt7~deb10u1 built with gcc 8 (Raspbian 8.3.0-6+rpi1)
-IDE-visual studio 2017-ssh connetction
Good morning. I have a question and post it.
When Raspbian is installed, the installed FFMPEG library is used.
I want to output a video display - file encoded in h264 using gtk3.0.
When I open the video file & find the codec and try to read the frame,I get an error and I'm asking.Error symptoms
- AVPacket struct memory padding? error
2.AVPacket-data error:Cannot access memory at address 0xxxxxxxxxxxx>
- AVPacket-stream_index value error- The stream_index and flags values seem to have been reversed.
my source code and error photos are attached.Thank you.
case 1 stream_index error (flags value ->stream_index)
case 2 data memory access error
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;}