Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1147520
  • 博文数量: 173
  • 博客积分: 4048
  • 博客等级:
  • 技术积分: 2679
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-12 18:53
文章分类

全部博文(173)

文章存档

2018年(1)

2016年(1)

2013年(1)

2012年(118)

2011年(52)

分类: 嵌入式

2011-12-07 13:31:04

使用编译命令:
gcc -o tutorial01 tutorial01.c -lavutil -lavformat -lavcodec -lswscale

源程序如下:

#include  
#include  
#include  
 
#include  
 
#define debug() fprintf(stderr,"%s#%i\n",__func__,__LINE__) 
 
static struct SwsContext *img_convert_ctx; 
 
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) 

    FILE  *pFile; 
    char   szFilename[32]; 
    int    y; 
  
    sprintf(szFilename, "frame%d.ppm", iFrame); 
    pFile = fopen(szFilename, "wb"); 
    if (pFile == NULL) { 
        return; 
    } 
 
    fprintf(pFile, "P6\n%d %d\n255\n", width, height); 
 
    for (y = 0; y < height; y++) { 
        fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile); 
    } 
 
    fclose(pFile); 

 
int main(int argc, char *argv[]) 

    AVFormatContext  *pFormatCtx; 
    int       i, videoStream; 
    AVCodecContext   *pCodecCtx; 
    AVCodec      *pCodec; 
    AVFrame      *pFrame; 
    AVFrame      *pFrameRGB; 
    AVPacket      packet; 
    int       frameFinished; 
    int               numBytes; 
    uint8_t       *buffer; 
 
    if (argc < 2) { 
        printf("Please provide a movie file\n"); 
        return -1; 
    } 
    fprintf(stderr,"ARG OK.\n"); 
    debug(); 
    av_register_all(); 
    fprintf(stderr,"av_register_all() OK.\n"); 
    debug(); 
     
    pFormatCtx = avformat_alloc_context(); // 分配空间 
    fprintf(stderr,"avformat_alloc_context() OK.\n"); 
    debug(); 
    if (av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL) != 0) { 
    //if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) { // 打开输入文件 
        return -1; 
    } 
    fprintf(stderr,"avformat_open_input() OK.\n"); 
    debug(); 
 
    if (av_find_stream_info(pFormatCtx) < 0) { 
        return -1; 
    } 
    fprintf(stderr,"av_find_stream_info() OK.\n"); 
    debug(); 
 
    dump_format(pFormatCtx, 0, argv[1], 0); 
    fprintf(stderr,"dump_format() OK.\n"); 
 
    debug(); 
    videoStream = -1; 
    for(i=0; inb_streams; i++) { 
        if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) { 
        videoStream = i; 
        break; 
        } 
    } 
    fprintf(stderr,"find CODEC_TYPE_VIDEO OK.\n"); 
    debug(); 
    if(videoStream == -1) { 
        return -1; 
    } 
    debug(); 
    pCodecCtx=pFormatCtx->streams[videoStream]->codec; 
    img_convert_ctx = sws_getContext( 
            pCodecCtx->width,  
            pCodecCtx->height, 
            pCodecCtx->pix_fmt,  
            pCodecCtx->width,  
            pCodecCtx->height,  
            PIX_FMT_RGB24,  
            SWS_BICUBIC,  
            NULL, NULL, NULL); 
    fprintf(stderr,"sws_getContext() OK.\n"); 
 
    debug(); 
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id); 
    if (pCodec == NULL) { 
        fprintf(stderr, "Unsupported codec!\n"); 
        return -1; 
    } 
    fprintf(stderr,"avcodec_find_decoder() OK.\n"); 
 
    debug(); 
    if (avcodec_open(pCodecCtx, pCodec) < 0) { 
        return -1; 
    } 
    fprintf(stderr,"avcodec_open() OK.\n"); 
    debug(); 
 
    pFrame = avcodec_alloc_frame(); 
    fprintf(stderr,"avcodec_alloc_frame() OK.\n"); 
    debug(); 
 
    pFrameRGB = avcodec_alloc_frame(); 
    if (pFrameRGB == NULL) { 
        return -1; 
    } 
    fprintf(stderr,"avcodec_alloc_frame() OK.\n"); 
    debug(); 
 
    numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, 
                          pCodecCtx->height); 
    fprintf(stderr,"avpicture_get_size() OK.\n"); 
    debug(); 
    buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); 
 
    debug(); 
    avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, 
               pCodecCtx->width, pCodecCtx->height); 
    fprintf(stderr,"avpicture_fill() OK.\n"); 
    debug();    i = 0; 
    while(av_read_frame(pFormatCtx, &packet) >= 0) { 
        if (packet.stream_index == videoStream) { 
            avcodec_decode_video(pCodecCtx, pFrame,  
                         &frameFinished, 
                         packet.data,  
                         packet.size); 
            if(frameFinished) { 
                sws_scale(img_convert_ctx,  
                      (const uint8_t **)pFrame->data,  
                      pFrame->linesize, 0,  
                      pCodecCtx->height,  
                      pFrameRGB->data,  
                      pFrameRGB->linesize); 
                if (++i <= 5) { 
                    SaveFrame(pFrameRGB, pCodecCtx->width,pCodecCtx->height,i); 
                } 
            } 
        } 
        av_free_packet(&packet); 
    } 
    debug(); 
 
    av_free(buffer); 
    av_free(pFrameRGB); 
 
    av_free(pFrame); 
 
    avcodec_close(pCodecCtx); 
 
    av_close_input_file(pFormatCtx); 
 
    return 0; 
}
阅读(2135) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~