热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用FFMpeg转码(精华)

使用ffmpeg进行视频格式转换的简单例子2006-12-1623:12主要参考FFMPEG里面的apiexample.c以及output_example.c编写intmain(in

使用ffmpeg进行视频格式转换的简单例子 2006-12-16 23:12

主要参考FFMPEG里面的apiexample.c以及output_example.c编写

int main(int argc, char **argv)
{
   char *filename = "d:\\1.asf";
char *outfilename = "d:\\test.mp4";

AVFormatContext *pFormatCtxDec, *pFormatCtxEnc;
AVCodecContext *pCodecCtxDec, *pCodecCtxEnc;
AVCodec *pCodecDec, *pCodecEnc;
AVFrame *pFrameDec, *pFrameEnc;
AVOutputFormat *pOutputFormat;
AVStream *video_st;

int i, videoStream;
int outbuf_size;
uint8_t *outbuf;

AVPacket packet;
int frameFinished,frames=0;
int out_size;

// Register all formats and codecs
av_register_all();

// Open video file
if(av_open_input_file(&pFormatCtxDec, filename, NULL, 0, NULL)!=0)
   return ; // Couldn't open file

// Retrieve stream information
if(av_find_stream_info(pFormatCtxDec)<0)
   return ; // Couldn't find stream information

// Find the first video stream
videoStream=-1;
for(i=0; inb_streams; i++) {
   if(pFormatCtxDec->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
pCodecCtxDec=pFormatCtxDec->streams[videoStream]->codec;

// Find the decoder for the video stream
pCodecDec=avcodec_find_decoder(pCodecCtxDec->codec_id);
if(pCodecDec==NULL)
   return ; // Codec not found

// Inform the codec that we can handle truncated bitstreams -- i.e.,
// bitstreams where frame boundaries can fall in the middle of packets
//if(pCodecDec->capabilities & CODEC_CAP_TRUNCATED)
// pCodecCtxDec->flags|=CODEC_FLAG_TRUNCATED;

// Open codec
if(avcodec_open(pCodecCtxDec, pCodecDec)<0)
   return ; // Could not open codec

// Allocate video frame
pFrameDec = avcodec_alloc_frame();
if(pFrameDec == NULL)
   return ;


// auto detect the output format from the name. default is mpeg.
pOutputFormat = guess_format(NULL, outfilename, NULL);
if (pOutputFormat == NULL)
   return;

// allocate the output media context
pFormatCtxEnc = av_alloc_format_context();
if (pFormatCtxEnc == NULL)
   return;
pFormatCtxEnc->oformat = pOutputFormat;
sprintf(pFormatCtxEnc->filename, "%s", outfilename);

video_st = av_new_stream(pFormatCtxEnc, 0); // 0 for video

pCodecCtxEnc = video_st->codec;

pCodecCtxEnc->codec_id = pOutputFormat->video_codec;
pCodecCtxEnc->codec_type = CODEC_TYPE_VIDEO;

// put sample parameters
pCodecCtxEnc->bit_rate = 200000;
// resolution must be a multiple of two
pCodecCtxEnc->width = pCodecCtxDec->width;
pCodecCtxEnc->height = pCodecCtxDec->height;
// frames per second
pCodecCtxEnc->time_base.den = 25;
pCodecCtxEnc->time_base.num = 1;
pCodecCtxEnc->pix_fmt = PIX_FMT_YUV420P;
pCodecCtxEnc->gop_size = 12;

     if (pCodecCtxEnc->codec_id == CODEC_ID_MPEG1VIDEO){
        
         pCodecCtxEnc->mb_decision=2;
     }
     // some formats want stream headers to be seperate
     if(!strcmp(pFormatCtxEnc->oformat->name, "mp4") || !strcmp(pFormatCtxEnc->oformat->name, "mov") || !strcmp(pFormatCtxEnc->oformat->name, "3gp"))
         pCodecCtxEnc->flags |= CODEC_FLAG_GLOBAL_HEADER;

// set the output parameters (must be done even if no parameters).
if (av_set_parameters(pFormatCtxEnc, NULL) <0) {
   return;
}

// find the video encoder
pCodecEnc = avcodec_find_encoder(pCodecCtxEnc->codec_id);
if (pCodecEnc == NULL)
   return;

// open it
if (avcodec_open(pCodecCtxEnc, pCodecEnc) <0) {
   return;
}

if (!(pFormatCtxEnc->oformat->flags & AVFMT_RAWPICTURE)) {
        
        
         outbuf_size = 500000;
         outbuf = av_malloc(outbuf_size);
     }

pFrameEnc= avcodec_alloc_frame();

     // open the output file, if needed
     if (!(pOutputFormat->flags & AVFMT_NOFILE)) {
         if (url_fopen(&pFormatCtxEnc->pb, outfilename, URL_WRONLY) <0) {
             fprintf(stderr, "Could not open '%s'\n", filename);
             return;
         }
     }

// write the stream header, if any
av_write_header(pFormatCtxEnc);

// Read frames and save frames to disk

while(av_read_frame(pFormatCtxDec, &packet)>=0)
{
   // Is this a packet from the video stream?
   if(packet.stream_index==videoStream)
   {
    // Decode video frame
    avcodec_decode_video(pCodecCtxDec, pFrameDec, &frameFinished, packet.data, packet.size);
   
    // Did we get a video frame?
    if(frameFinished)
    {
     frames++;
    
     pFrameEnc->data[0] = pFrameDec->data[0];
     pFrameEnc->data[1] = pFrameDec->data[1];
     pFrameEnc->data[2] = pFrameDec->data[2];
     pFrameEnc->linesize[0] = pFrameDec->linesize[0];
     pFrameEnc->linesize[1] = pFrameDec->linesize[1];
     pFrameEnc->linesize[2] = pFrameDec->linesize[2];

     if (pFormatCtxEnc->oformat->flags & AVFMT_RAWPICTURE) {
     
      AVPacket pkt;
      av_init_packet(&pkt);
     
      pkt.flags |= PKT_FLAG_KEY;
      pkt.stream_index= video_st->index;
      pkt.data= (uint8_t *)pFrameEnc;
      pkt.size= sizeof(AVPicture);
     
      av_write_frame(pFormatCtxEnc, &pkt);
     } else {
      // encode the image
      out_size = avcodec_encode_video(pCodecCtxEnc, outbuf, outbuf_size, pFrameEnc);
      // if zero size, it means the image was buffered
      if (out_size != 0) {
       AVPacket pkt;
       av_init_packet(&pkt);
      
       pkt.pts= pCodecCtxEnc->coded_frame->pts;
       if(pCodecCtxEnc->coded_frame->key_frame)
        pkt.flags |= PKT_FLAG_KEY;
       pkt.stream_index= video_st->index;
       pkt.data= outbuf;
       pkt.size= out_size;
      
       // write the compressed frame in the media file
       av_write_frame(pFormatCtxEnc, &pkt);
      }
     }
    }
   }
   // Free the packet that was allocated by av_read_frame
   av_free_packet(&packet);
}

// get the delayed frames
for(; out_size; i++) {
   out_size = avcodec_encode_video(pCodecCtxEnc, outbuf, outbuf_size, NULL);
   if (out_size != 0) {
    AVPacket pkt;
    av_init_packet(&pkt);
   
    pkt.pts= pCodecCtxEnc->coded_frame->pts;
    if(pCodecCtxEnc->coded_frame->key_frame)
     pkt.flags |= PKT_FLAG_KEY;
    pkt.stream_index= video_st->index;
    pkt.data= outbuf;
    pkt.size= out_size;
   
    // write the compressed frame in the media file
    av_write_frame(pFormatCtxEnc, &pkt);
   }
}

// Close the codec
avcodec_close(pCodecCtxDec);
avcodec_close(pCodecCtxEnc);

// Free the YUV frame
av_free(pFrameDec);
av_free(pFrameEnc);

av_free(outbuf);

// write the trailer, if any
     av_write_trailer(pFormatCtxEnc);

// free the streams
     for(i = 0; i nb_streams; i++) {
   av_freep(&pFormatCtxEnc->streams[i]->codec);
         av_freep(&pFormatCtxEnc->streams[i]);
     }

     if (!(pOutputFormat->flags & AVFMT_NOFILE)) {
        
         url_fclose(&pFormatCtxEnc->pb);
     }


     av_free(pFormatCtxEnc);

// Close the video file
av_close_input_file(pFormatCtxDec);

av_free_static();
}


推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
author-avatar
哗锅_348
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有