ffmpeg2.1对HEVC/H.265视频进行解码的例子

新版的ffmpeg 2.1已经加入了对最新视频编解码标准H.265/HEVC的支持,因此可以解码该格式的视频了。这对视频产业来说将起到一种巨大的推动作用。本文所示的demo是一个简单的H.265格式视频的playback程序,是在http://blog.csdn.net/mu399/article/details/5814859这篇文章的基础上针对新版ffmpeg2.1做了部分修改。与参考文章一样,这个demo同样没有加入播放延迟,所以视频的帧率是不正常的,随着学习的深入会逐渐解决这个问题。工程的下载地址为:http://download.csdn.net/detail/shaqoneal/6571657

这个工程需要用到ffmpeg和SDL的库,如何将这些库加入到工程中,有很多教程可以参考,就不在这里赘述了,上传到资源中的工程已经设置好了。

文件很简单,头文件如下:

//header.h
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"

#ifdef __cplusplus
}
#endif

源文件:

//main.cpp
#include "header.h"
#include <stdio.h>
#include "SDL/include/SDL.h"
#include <stdlib.h>
#include <string.h>
#include <math.h> 

static int sws_flags = SWS_BICUBIC; 

int main(int argc, char *argv[])
 {
	AVFormatContext *pFormatCtx = NULL;
    int i, videoStream(-1);
    AVCodecContext *pCodecCtx;
    AVCodec *pCodec;
    AVFrame *pFrame;
    AVPacket packet;
    int frameFinished;
    float aspect_ratio;
    AVCodecContext *aCodecCtx;
    SDL_Overlay *bmp;
    SDL_Surface *screen;
    SDL_Rect rect;
    SDL_Event event;
    if(argc < 2)
    {
        fprintf(stderr, "Usage: test /n");
        exit(1);
    }  

    av_register_all();  

    if(avformat_open_input(&pFormatCtx,argv[1],NULL,NULL))
        return -1; // Couldn't open file
    if(av_find_stream_info(pFormatCtx)<0)
        return -1; // Couldn't find stream information
    // Dump information about file onto standard error
//    dump_format(pFormatCtx, 0, argv[1], 0);  

    // Find the first video stream
    for(i=0; i<pFormatCtx->nb_streams; i++)
    {
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO && videoStream<0)
        {
            videoStream=i;
        }
    }
    if(videoStream==-1)
      return -1; // Didn't find a video stream  

    // Get a pointer to the codec context for the video stream  

    pCodecCtx=pFormatCtx->streams[videoStream]->codec;
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL)
    {
        fprintf(stderr, "Unsupported codec!/n");
        return -1; // Codec not found
    }
    // Open codec
    if(avcodec_open2(pCodecCtx, pCodec, NULL)<0)
        return -1; // Could not open codec  

    // Allocate video frame
    pFrame=avcodec_alloc_frame();  

    uint8_t *buffer;
    int numBytes;
    // 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));  

    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
    {
        fprintf(stderr, "Could not initialize SDL - %s/n", SDL_GetError());
        exit(1);
    }  

#ifndef __DARWIN__
    screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
#else
    screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0);
#endif
    if(!screen)
    {
        fprintf(stderr, "SDL: could not set video mode - exiting/n");
        exit(1);
    }  

    bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,
        SDL_YV12_OVERLAY, screen);  

    static struct SwsContext *img_convert_ctx;
    if (img_convert_ctx == NULL)
    {
        img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
                                         pCodecCtx->pix_fmt,
                                         pCodecCtx->width, pCodecCtx->height,
                                         PIX_FMT_YUV420P,
                                         sws_flags, NULL, NULL, NULL);
        if (img_convert_ctx == NULL)
        {
            fprintf(stderr, "Cannot initialize the conversion context/n");
            exit(1);
        }
    }
    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_video2(pCodecCtx, pFrame, &frameFinished, &packet);

            // Did we get a video frame?
            if(frameFinished)
            {
                // Convert the image from its native format to RGB
                /*sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
                      0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);*/
                // Save the frame to disk
                /*if(++i<=5)
                    SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);*/
                SDL_LockYUVOverlay(bmp);
                AVPicture pict;
                pict.data[0] = bmp->pixels[0];
                pict.data[1] = bmp->pixels[2];
                pict.data[2] = bmp->pixels[1];  

                pict.linesize[0] = bmp->pitches[0];
                pict.linesize[1] = bmp->pitches[2];
                pict.linesize[2] = bmp->pitches[1];  

                // Convert the image into YUV format that SDL uses
                /*img_convert(&pict, PIX_FMT_YUV420P,
                    (AVPicture *)pFrame, pCodecCtx->pix_fmt,
                    pCodecCtx->width, pCodecCtx->height);*/
                sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
                    0, pCodecCtx->height, pict.data, pict.linesize);
                SDL_UnlockYUVOverlay(bmp);
                rect.x = 0;
                rect.y = 0;
                rect.w = pCodecCtx->width;
                rect.h = pCodecCtx->height;
                SDL_DisplayYUVOverlay(bmp, &rect);
                //Sleep(60);
            }
        }  

        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);  

        SDL_PollEvent(&event);
        switch(event.type)
        {
        case SDL_QUIT:
            SDL_Quit();
            exit(0);
            break;
        default: break;
        }
    };
    // 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);
    return 0;
};

今后一段时间里讲尽可能详细地解析上面的每一个类、语句的结构和作用,最终的目的是彻底搞通ffmpeg进行视频处理的原理,可以方便地完成基于ffmpeg的各种开发。一起加油吧!

时间: 2024-09-20 08:20:41

ffmpeg2.1对HEVC/H.265视频进行解码的例子的相关文章

HEVC/H.265硬件编码器实现杂谈

国际视频编码标准HEVC已经发布两年有余,市场上关于支持HEVC的硬件也日益涌现,本文借鉴了各方面资源做了综合与概述,给出了HEVC硬件编码器实现的基本方法等重要网络资源. 一.系统设计要点 对于HEVC/H.265视频编码而言,采用了比以往视频标准更加先进和灵活的编码方法,在性能上有比较明显的优势,但对硬件实现也是一个很大的挑战,其实现复杂度和计算量几倍于H.264标准,这对基于FPGA/ASIC/SOC硬件平台实现的H.265编码器设计提出了更高的要求. 要设计一个优秀的HEVC/H.265

MilkPlayer已支持HEVC/H.265视频解码

主打支持HEVC/H.265转码视频播放概念的MilkPlayer牛奶播放器 ,于3.17日推出0.2.0版本.本次版本升级,新增了众多用户需求的在线播放功能,播放1080P视频文件的响应速度也明显加快,缓冲进度提示也有所完善,同时还增加了精彩推荐栏目. 本次新增,MilkPlayer0.2.0解决了众多用户关于在线播放的需求,用户可以通过MilkPlayer在线观看HEVC/H265电影. 以下是在线播放画质效果: 新增精彩推荐功能,可以随时为用户提供MikPlayer的最新资讯与动态,用户也

直播平台面临苹果抢食 云帆加速首推H.265视频直播传输方案

5标准 现在用户对视频质量的要求也越来越高,高清.4K等已经成为当前视频业务的主流发展方向.视频清晰度的提升带来了数据量的大幅增长,而现有的编码标准(如H.264.MPEG-2等)的数据压缩能力却难以同步增长,所以在现有的网络环境下,很多优质视频不得不降低质量标准,采用多种方式降低码率,牺牲质量换流畅播放. 在此背景下,市场呼吁一种新的能够提供更高压缩比例的视频编码技术,以应对当前视频业务的发展,H.265(标准全称为高效视频编码High Efficiency Video Coding)视频编码

科达H.265视频监控解决方案,全力为深圳湾科技生态园安保服务

在生态环境压力不断增大的情形下,地处深圳湾区核心地带的深圳湾科技生态园,以生态为核心,集生态产业.生态环境.生态经营为一体,注重经济.社会与环境三大效益的平衡,打造全新的第三代绿色产业园区. 在绿色生态和可持续发展的大背景下,园区在选用监控产品上也对节能环保方面有了较多的考量,科达全系列端到端的H.265视频监控解决方案,高效节能,最终获得了一致好评,有幸为这个现代化产业园区安保服务. 端到端的H.265全系列解决方案 园区高楼林立,装修精致,监控密度高,要求产品精致小巧,节能环保.方案最终选择

ITU批准H.265视频标准 比H.264减少一半带宽

国际电信联盟的一个组织已经批准H.264视频编码标准的后续标准,为未来的视频传输敞开了大门.采用这个标准传输视频所需要的带宽仅是目前所需带宽的一半.随着显示屏分辨率在未来10年里不断提高,国际电信联盟的H.265标准将帮助在智能手机.平板电脑.电视机和其它设备之间传送视频.这个标准将帮助减少有线和无线网络的负担.视频目前占这些网络流量的很大一部分.随着产品和服务的增长超过目前的技术限制,厂商和服务提供商 预计将逐步采用这个新标准.国际电信联盟称,名为MPEG-4的当前的技术规格是世界上使用最多的

H.264视频编解码SoC满足高清DVR设计需求

硬盘录像机(DVR)作为监控系统的核心部件之一,在10年里高速发展,从模拟磁带机的替代品演变成具有自己独特价值的专业监控数字平台,并被市场广泛接受.监控系统伴随DVR这些年的发展向着IP化.智能化发展. 根 据行业用户的需求,DVR由以下几个方向需要被行业关注:1.DVR的编码方式向更高压缩效率的标准H.264发展:2.录像分辨率从 CIF(352*288分辨率) 向D1(720*576).720P.1080P发展:3.现场监控分辨率也从D1向HD高清发展:4.封闭子系统向开放IP架构系统发展:

基于ffmpeg的简单音视频编解码的例子

近日需要做一个视频转码服务器,对我这样一个在该领域的新手来说却是够我折腾一番,在别人的建议下开始研究开源ffmpeg项目,下面是在代码中看到的一 段例子代码,对我的学习非常有帮助.该例子代码包含音频的解码/编码和视频的编码/解码,其中主要用到编解码的libavcodec组件.以下是完整的例 子,代码自身的注释足够清晰了./**  * @file  * libavcodec API use example.  *  * Note that libavcodec only handles codec

视频业内独家“免下载”H.265技术落户乐视网

图示:乐视网H265高清体验厅家里带宽有限,还想看高质量网络视频?想试试高端大气上档次的H.265视频转码技术,却又不愿被迫下载视频网站的客户端?如果你是高画质视频控,如果你不想因电脑内存太大而拖累了你的网速,那么乐视网最新推出的视频业内独家"免下载"H.265 视频转码技术一定让你爱不释手.H.265是时下视频行业最潮的视频编码技术,有了它,你就可以在带宽有限的情况下看到更高质量的网络视频,比如你就可以在低带宽条件下享受720P或1080P超高清视频了.目前,部分视频网站也有了H.2

全面解读:H.265在安防行业应用及价值

在过去的10年里,视频监控领域的主要视频压缩标准是H.264.今天,H.264占据了网络视频码流的80%左右.现在的摄像机主流分辨率是720p或1080p等高清级别的,但是几年前的主流分辨率是VGA级别的.H.264在视频监控IP化过程中扮演了重要的角色. 但是今天,在视频监控领域我们仍然面临着诸多挑战.随着摄像机分辨率的不断增加,出现了更大的百万级像素(MegaPixel)sensor.全景摄像机.甚至是千万级像素sensor.同时面临着远程观看这样的大分辨率视频而带来的网络传输压力,以及码流