ffplay 将视频帧转换成bmp图片

ffplay 将视频帧转换成bmp图片

static  int video_thread2( void *arg)
{
    AVPacket pkt = { 0 };
    VideoState * is = (VideoState *)arg;
    AVFrame *pFrame = avcodec_alloc_frame();
    int64_t pts_int = AV_NOPTS_VALUE, pos = -1;
     double pts;
     int ret;
    
     for (;;) 
    {
         while ( is->paused && ! is->videoq.abort_request)
            SDL_Delay(10);
        
        avcodec_get_frame_defaults(pFrame);
        av_free_packet(&pkt);

        ret = get_video_frame( is, pFrame, &pts_int, &pkt);
         if (ret < 0)
             goto the_end;

         if (!ret)
             continue;

        pts = pts_int * av_q2d( is->video_st->time_base);
        ret = queue_picture( is, pFrame, pts, pkt.pos);

         if (ret < 0)
             goto the_end;

         if ( is->step)
            stream_toggle_pause( is);
        
         int nWidth = pFrame->width;
         int nHeight = pFrame->height;
        AVPixelFormat srcfmt = (AVPixelFormat)pFrame->format;
        AVPixelFormat dstfmt = AV_PIX_FMT_BGR24; // AV_PIX_FMT_RGB24; // AV_PIX_FMT_BGR24;
        AVFrame *pFrameRGB;
        pFrameRGB = avcodec_alloc_frame();

//          int src_bytes_num = avpicture_get_size(srcfmt, nWidth, nHeight);
//          uint8_t* src_buff = (uint8_t*)av_malloc(src_bytes_num);
//          avpicture_fill((AVPicture*)pFrame, src_buff, srcfmt, nWidth, nHeight);

         int dst_bytes_num = avpicture_get_size(dstfmt, nWidth, nHeight);
        uint8_t* dst_buff = (uint8_t*)av_malloc(dst_bytes_num);
        avpicture_fill((AVPicture*)pFrameRGB, dst_buff, dstfmt, nWidth, nHeight);

        SwsContext* pSwsCtx = sws_getContext(nWidth, nHeight,
            srcfmt,
            nWidth, nHeight,
            dstfmt,
            SWS_BICUBIC,
            NULL,NULL,NULL);

         ///   <转换图像格式>
        sws_scale(pSwsCtx, pFrame->data, pFrame->linesize, 0, nHeight, pFrameRGB->data, pFrameRGB->linesize);

         static  int nnn = 0;
        
         if ((nnn++ % 5) == 0)
        {
             // saveAsBitmap(pFrameRGB, nWidth, nHeight, nnn);
        }
    }

the_end:
    avcodec_flush_buffers( is->video_st->codec);
    av_free_packet(&pkt);
    avcodec_free_frame(&pFrame);
     return 0;
}


bool saveAsBitmap(AVFrame *pFrameRGB,  int width,  int height,  int iFrame)  
{  
     if (NULL == pFrameRGB->data[0])
    {
         return  false;
    }

    FILE *pFile = NULL;  
    BITMAPFILEHEADER bmpheader;  
    BITMAPINFO bmpinfo;  

     char fileName[32];  
     int bpp = 24;  

     //  open file  
    sprintf(fileName, "./images/frame%d.bmp", iFrame);  
    pFile = fopen(fileName, "wb");  
     if (!pFile)  
         return  false;  

    bmpheader.bfType = ('M' <<8)|'B';  
    bmpheader.bfReserved1 = 0;  
    bmpheader.bfReserved2 = 0;  
    bmpheader.bfOffBits =  sizeof(BITMAPFILEHEADER) +  sizeof(BITMAPINFOHEADER);  
    bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;  

    bmpinfo.bmiHeader.biSize =  sizeof(BITMAPINFOHEADER);  
    bmpinfo.bmiHeader.biWidth = width;  
    bmpinfo.bmiHeader.biHeight = -height;  // reverse the image  
    bmpinfo.bmiHeader.biPlanes = 1;  
    bmpinfo.bmiHeader.biBitCount = bpp;  
    bmpinfo.bmiHeader.biCompression = BI_RGB;  
    bmpinfo.bmiHeader.biSizeImage = 0;  
    bmpinfo.bmiHeader.biXPelsPerMeter = 100;  
    bmpinfo.bmiHeader.biYPelsPerMeter = 100;  
    bmpinfo.bmiHeader.biClrUsed = 0;  
    bmpinfo.bmiHeader.biClrImportant = 0;  

    fwrite(&bmpheader,  sizeof(BITMAPFILEHEADER), 1, pFile);  
    fwrite(&bmpinfo.bmiHeader,  sizeof(BITMAPINFOHEADER), 1, pFile);  
     uint8_t *buffer = pFrameRGB->data[0];  
//      for (int h=0; h<height; h++)  
//      {  
//          for (int w=0; w<width; w++)  
//          {  
//              fwrite(buffer+2, 1, 1, pFile);  
//              fwrite(buffer+1, 1, 1, pFile);  
//              fwrite(buffer, 1, 1, pFile);  
//  
//              buffer += 3;  
//          }  
//      }  

    fwrite(buffer,width*height*bpp/8,1,pFile);

    fclose(pFile);  

     return  true;  

你可能感兴趣的:(ffplay 将视频帧转换成bmp图片)