ffmpeg转TS流

来源:互联网 发布:淘宝助理天猫版不好用 编辑:程序博客网 时间:2024/04/30 00:39
各位好,我的问题是这样的。我有一个 h264编码的ES流视频文件,我想用ffmpeg来把视频文件封装成TS流。代码如下(部分代码来自网上,谢谢共享这份代码的网友)
  1. #include "stdafx.h"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <math.h>

  6. #ifdef __cplusplus
  7. extern "C"{
  8. #endif

  9. #include "libavformat\avformat.h"
  10. #include "libavcodec\avcodec.h"
  11. #include "libavutil\avutil.h"
  12. #include "libavutil\rational.h"
  13. #include "libavdevice\avdevice.h"
  14. #include "libavutil/mathematics.h"
  15. #include "libswscale/swscale.h"

  16. #ifdef __cplusplus
  17. }
  18. #endif //__cplusplus


  19. static AVStream* add_output_stream(AVFormatContext* output_format_context, AVStream* input_stream)
  20. {
  21.         AVCodecContext* input_codec_context = NULL;
  22.         AVCodecContext* output_codec_context = NULL;
  23.        
  24.         AVStream* output_stream = NULL;
  25.         output_stream = av_new_stream(output_format_context, 0);
  26.         if (!output_stream)
  27.         {
  28.                 printf("Call av_new_stream function failed\n");
  29.                 return NULL;
  30.         }

  31.         input_codec_context = input_stream->codec;
  32.         output_codec_context = output_stream->codec;

  33.         output_codec_context->codec_id = input_codec_context->codec_id;
  34.         output_codec_context->codec_type = input_codec_context->codec_type;
  35.         output_codec_context->codec_tag = input_codec_context->codec_tag;
  36.         output_codec_context->bit_rate = input_codec_context->bit_rate;
  37.         output_codec_context->extradata = input_codec_context->extradata;
  38.         output_codec_context->extradata_size = input_codec_context->extradata_size;

  39.         if (av_q2d(input_codec_context->time_base) * input_codec_context->ticks_per_frame > av_q2d(input_stream->time_base) && av_q2d(input_stream->time_base) < 1.0 / 1000)
  40.         {
  41.                 output_codec_context->time_base = input_codec_context->time_base;
  42.                 output_codec_context->time_base.num *= input_codec_context->ticks_per_frame;
  43.         }
  44.         else
  45.         {
  46.                 output_codec_context->time_base = input_stream->time_base;
  47.         }
  48.         switch (input_codec_context->codec_type)
  49.         {
  50.         case AVMEDIA_TYPE_AUDIO:
  51.                 output_codec_context->channel_layout = input_codec_context->channel_layout;
  52.                 output_codec_context->sample_rate = input_codec_context->sample_rate;
  53.                 output_codec_context->channels = input_codec_context->channels;
  54.                 output_codec_context->frame_size = input_codec_context->frame_size;
  55.                 if ((input_codec_context->block_align == 1 && input_codec_context->codec_id == CODEC_ID_MP3) || input_codec_context->codec_id == CODEC_ID_AC3)
  56.                 {
  57.                         output_codec_context->block_align = 0;
  58.                 }
  59.                 else
  60.                 {
  61.                         output_codec_context->block_align = input_codec_context->block_align;
  62.                 }
  63.                 break;
  64.         case AVMEDIA_TYPE_VIDEO:
  65.                 output_codec_context->pix_fmt = input_codec_context->pix_fmt;
  66.                 output_codec_context->width = input_codec_context->width;
  67.                 output_codec_context->height = input_codec_context->height;
  68.                 output_codec_context->has_b_frames = input_codec_context->has_b_frames;
  69.                 if (output_format_context->oformat->flags & AVFMT_GLOBALHEADER)
  70.                 {
  71.                         output_codec_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
  72.                 }
  73.                 break;
  74.         default:
  75.                 break;
  76.         }

  77.         return output_stream;
  78. }

  79. int _tmain(int argc, _TCHAR* argv[])
  80. {

  81.         const char* input = "F:\\VideoPlayer\\debug\\StreamTotal.h264";
  82.         const char* output_prefix = NULL;
  83.         char* segment_duration_check = 0;
  84.         const char* index = NULL;
  85.         char* tmp_index = NULL;
  86.         const char* http_prefix = NULL;
  87.         long max_tsfiles = NULL;
  88.         double prev_segment_time = 0;
  89.         double segment_duration = 0;
  90.        
  91.         AVInputFormat* ifmt = NULL;
  92.         AVOutputFormat* ofmt = NULL;
  93.         AVFormatContext* ic = NULL;
  94.         AVFormatContext* oc = NULL;
  95.         AVStream* video_st = NULL;
  96.         AVStream* audio_st = NULL;
  97.         AVCodec* codec = NULL;
  98.         AVDictionary* pAVDictionary = NULL;

  99.         av_register_all();

  100.         char szError[256] = {0};
  101.         int nRet = avformat_open_input(&ic, input, ifmt, &pAVDictionary);
  102.         if (nRet != 0)
  103.         {
  104.                 av_strerror(nRet, szError, 256);
  105.                 printf(szError);
  106.                 printf("\n");
  107.                 printf("Call avformat_open_input function failed!\n");
  108.                 return 0;
  109.         }

  110.         if (av_find_stream_info(ic) < 0)
  111.         {
  112.                 printf("Call av_find_stream_info function failed!\n");
  113.                 return 0;
  114.         }

  115.         ofmt = av_guess_format("mpegts", NULL, NULL);
  116.         if (!ofmt)
  117.         {
  118.                 printf("Call av_guess_format function failed!\n");
  119.                 return 0;
  120.         }

  121.         oc = avformat_alloc_context();
  122.         if (!oc)
  123.         {
  124.                 printf("Call av_guess_format function failed!\n");
  125.                 return 0;
  126.         }
  127.         oc->oformat = ofmt;
  128.        
  129.         int video_index = -1, audio_index = -1;
  130.         for (unsigned int i = 0; i < ic->nb_streams && (video_index < 0 || audio_index < 0); i++)
  131.         {
  132.                 switch (ic->streams[i]->codec->codec_type)
  133.                 {
  134.                 case AVMEDIA_TYPE_VIDEO:
  135.                         video_index = i;
  136.                         ic->streams[i]->discard = AVDISCARD_NONE;
  137.                         video_st = add_output_stream(oc, ic->streams[i]);
  138.                         break;
  139.                 case AVMEDIA_TYPE_AUDIO:
  140.                         audio_index = i;
  141.                         ic->streams[i]->discard = AVDISCARD_NONE;
  142.                         audio_st = add_output_stream(oc, ic->streams[i]);
  143.                         break;
  144.                 default:
  145.                         ic->streams[i]->discard = AVDISCARD_ALL;
  146.                         break;
  147.                 }
  148.         }
  149.         codec = avcodec_find_decoder(video_st->codec->codec_id);
  150.         if (codec == NULL)
  151.         {
  152.                 printf("Call avcodec_find_decoder function failed!\n");
  153.                 return 0;
  154.         }

  155.         if (avcodec_open(video_st->codec, codec) < 0)
  156.         {
  157.                 printf("Call avcodec_open function failed !\n");
  158.                 return 0;
  159.         }

  160.         if (avio_open(&oc->pb, "F:\\VideoPlayer\\debug\\264.ts", AVIO_FLAG_WRITE) < 0)
  161.         {
  162.                 return 0;
  163.         }

  164.         if (avformat_write_header(oc, &pAVDictionary))
  165.         {
  166.                 printf("Call avformat_write_header function failed.\n");
  167.                 return 0;
  168.         }

  169.         uint8_t *dummy = NULL;  
  170.         int dummy_size = 0;  
  171.         AVBitStreamFilterContext* bsfc =  av_bitstream_filter_init("h264_mp4toannexb");  
  172.         if(bsfc == NULL)  
  173.         {  
  174.            return -1;  
  175.         }   

  176.         int decode_done = 0;
  177.         do
  178.         {
  179.                 double segment_time = 0;
  180.                 AVPacket packet;
  181.                 decode_done = av_read_frame(ic, &packet);
  182.                 if (decode_done < 0)
  183.                         break;
  184.                        
  185.                 if (av_dup_packet(&packet) < 0)
  186.                 {
  187.                         printf("Call av_dup_packet function failed\n");
  188.                         av_free_packet(&packet);
  189.                         break;
  190.                 }

  191.                 static int nCount = 0;
  192.                 if (nCount++ < 20)
  193.                 {
  194.                         printf("The packet.stream_index is %ld\n", packet.stream_index);
  195.                 }

  196.                 if (packet.stream_index == video_index && (packet.flags & AV_PKT_FLAG_KEY))
  197.                 {
  198.             segment_time = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
  199.         }
  200.         else if (packet.stream_index == audio_index) {
  201.             segment_time = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
  202.         }
  203.         else {
  204.             segment_time = prev_segment_time;
  205.         }
  206.                 nRet = av_interleaved_write_frame(oc, &packet);
  207.                 if (nRet < 0)
  208.                 {
  209.                         printf("Call av_interleaved_write_frame function failed\n");
  210.                 }
  211.                 else if (nRet > 0)
  212.                 {
  213.                         printf("End of stream requested\n");
  214.                         av_free_packet(&packet);
  215.                         break;
  216.                 }
  217.                 av_free_packet(&packet);
  218.         }while(!decode_done);

  219.         av_write_trailer(oc);

  220.         av_bitstream_filter_close(bsfc);  
  221.         avcodec_close(video_st->codec);
  222.         for(unsigned int k = 0; k < oc->nb_streams; k++)
  223.         {
  224.                 av_freep(&oc->streams[k]->codec);
  225.                 av_freep(&oc->streams[k]);
  226.         }
  227.         av_free(oc);
  228.         getchar();
  229.         return 0;
  230. }
0 0
原创粉丝点击