利用ffmpeg0.5 和libjpeg實現抽取視訊框架並將其儲存為jpeg檔案格式程式

來源:互聯網
上載者:User

簡單修改網上關於ffmpeg的例子,實現提取視訊框架並將其儲存為jpeg映像的來源程式。

由於ffmpeg0.5不在相容img_convert函數,使用sws_scale函數修改了實現YUV色彩空間到RGB空間的轉換

這裡面一定要注意sws_getCachedContext函數參數的設定問題,一旦設定錯了,會出現解碼出來的映像出現3個現象!

直接使用libjpeg庫實現映像資料的jpeg壓縮

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>//注意要包含此標頭檔與sprintf函數相關

extern "C"
{
 //ffmpeg相關的標頭檔
 #include "avstring.h"
 #include "avformat.h"
 #include "swscale.h"
 #include "opt.h"
 //libjpeg相關的標頭檔

 #include "jpeglib.h"

}
int framenum=0 ;
//static int  sws_flags = SWS_BICUBIC ;

//實現視訊框架的jpeg壓縮
void draw_jpeg(AVPicture *pic,int width,int height)
{
 char fname[128] ;
// AVPicture my_pic ;
 struct jpeg_compress_struct cinfo ;
 struct jpeg_error_mgr jerr ;
 JSAMPROW  row_pointer[1] ;
 int row_stride ;
 uint8_t *buffer ;
 FILE *fp ;
 
 //vfmt2rgb(my_pic,pic) ;
    buffer = pic->data[0];

#ifdef __MINGW32__
    sprintf(fname, "%sDLPShot-%d.jpg", "frame", framenum++);
#else
    sprintf(fname, "%sDLPShot-%d.jpg", "frame", framenum++);
#endif
    fp = fopen (fname, "wb");
    if (fp == NULL)
    {
        av_log(NULL, AV_LOG_ERROR, "fopen %s error/n", fname);
        return;
    }
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, fp);

    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
   

    jpeg_set_quality(&cinfo, 80,true);
   
   
    jpeg_start_compress(&cinfo, TRUE);

    row_stride = width * 3;
    while (cinfo.next_scanline < height)
    {
        row_pointer[0] = &buffer[cinfo.next_scanline * row_stride];
        (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    fclose(fp);
    jpeg_destroy_compress(&cinfo);
 printf("compress %d frame finished!/n",framenum) ;
    return ;
 
}

void main()
{
 AVFormatContext *pFormatCtx;
 static char *ifilename="1.asf" ;
 AVStream *st;
 AVCodecContext *pCodecCtx;
 AVCodec *pCodec;
 AVFrame *pFrame,*pFrameRGB;
 uint8_t *buffer;
 AVPacket packet;
 struct SwsContext *img_convert_ctx=NULL;
 int numBytes;

 int i,videoStream=-1,frameFinished;
 

 av_register_all();
 if(av_open_input_file(&pFormatCtx, ifilename, NULL, 0, NULL)!=0)
 {
  printf("open video failed!/n") ;
  return ;
 }

 //read information about input file ;
 if(av_find_stream_info(pFormatCtx)<0)
 {
  printf("get information failed!/n") ;
  return ;
 }
//print information about file
 dump_format(pFormatCtx, 0, ifilename, 0);
 
 for(i=0; i<pFormatCtx->nb_streams; i++)
 {
  if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
  {
  videoStream=i;
  break;
  }
 }
 if(videoStream==-1)
  return ; // Didn't find a video stream

  // Get a pointer to the codec context for the video stream
 st=pFormatCtx->streams[videoStream] ;
 pCodecCtx=st->codec;

 // Find the decoder for the video stream
 pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
 if(pCodec==NULL) {
  fprintf(stderr, "Unsupported codec!/n");
  return ; // Codec not found
 }
// Open codec
 if(avcodec_open(pCodecCtx, pCodec)<0)
 {
  printf("open encoder failed!") ;
  return ;
 }

 // Allocate video frame
 pFrame=avcodec_alloc_frame();
 
 // Allocate an AVFrame structure
 pFrameRGB=avcodec_alloc_frame();
 if(pFrameRGB==NULL)
 {
  printf("allocate AVframe failed!/n") ;
  return ;
 }

 // Determine required buffer size and allocate buffer
 numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
                            pCodecCtx->height);
 buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
 
 // Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
 avpicture_fill((AVPicture *)pFrameRGB, buffer,PIX_FMT_RGB24,
 //  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
     pCodecCtx->width, pCodecCtx->height);
 //pFrameRGB->alloc_picture(PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height) ;

 i=0;
 while(av_read_frame(pFormatCtx, &packet)>=0)
 {
  // Is this a packet from the video stream?
  if(packet.stream_index==videoStream)
  {
 // Decode video frame
   avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
                         packet.data, packet.size);
   
    // Did we get a video frame?
   if(frameFinished)
   {
  // Convert the image from its native format to RGB
   
    if(img_convert_ctx==NULL)
    {
      img_convert_ctx=sws_getCachedContext(img_convert_ctx,pCodecCtx->width,pCodecCtx->height,
      //PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,
       pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24 ,
     SWS_X ,NULL,NULL,NULL) ;
      if (img_convert_ctx == NULL)
      {
      
       printf("can't init convert context!/n") ;
       return ;
      }

    }
    sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
         0, pCodecCtx->width, pFrameRGB->data, pFrameRGB->linesize);
   //av_picture_copy((AVPicture*)pFrameRGB,(AVPicture*)pFrame,PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height) ;

   // Save the frame to disk
   int a=++i ;
    if((a>50)&&(a<100))
    // SaveFrame(pFrameRGB, pCodecCtx->width,
    //  pCodecCtx->height, i);
    draw_jpeg((AVPicture*)pFrameRGB,pCodecCtx->width,pCodecCtx->height) ;
   }
  }
   
  // Free the packet that was allocated by av_read_frame
 av_free_packet(&packet);
 }
 // Free the RGB image
 av_free(buffer);
 av_free(pFrameRGB);

// Free the YUV frame
 av_free(pFrame);

// Close the codec
 avcodec_close(pCodecCtx);

// Close the video file
 av_close_input_file(pFormatCtx);

 

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.