使用ffmpeg封装ts流的问题

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
 
#ifdef __cplusplus
extern  "C" {
#endif
 
#include "libavformat\avformat.h"
#include "libavcodec\avcodec.h"
#include "libavutil\avutil.h"
#include "libavutil\rational.h"
#include "libavdevice\avdevice.h"
#include "libavutil/mathematics.h"
#include "libswscale/swscale.h"
 
#ifdef __cplusplus
}
#endif //__cplusplus
 
 
static  AVStream* add_output_stream(AVFormatContext* output_format_context, AVStream* input_stream)
{
         AVCodecContext* input_codec_context = NULL;
         AVCodecContext* output_codec_context = NULL;
         
         AVStream* output_stream = NULL;
         output_stream = av_new_stream(output_format_context, 0);
         if  (!output_stream)
         {
                 printf ( "Call av_new_stream function failed\n" );
                 return  NULL;
         }
 
         input_codec_context = input_stream->codec;
         output_codec_context = output_stream->codec;
 
         output_codec_context->codec_id = input_codec_context->codec_id;
         output_codec_context->codec_type = input_codec_context->codec_type;
         output_codec_context->codec_tag = input_codec_context->codec_tag;
         output_codec_context->bit_rate = input_codec_context->bit_rate;
         output_codec_context->extradata = input_codec_context->extradata;
         output_codec_context->extradata_size = input_codec_context->extradata_size;
 
         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)
         {
                 output_codec_context->time_base = input_codec_context->time_base;
                 output_codec_context->time_base.num *= input_codec_context->ticks_per_frame;
         }
         else
         {
                 output_codec_context->time_base = input_stream->time_base;
         }
         switch  (input_codec_context->codec_type)
         {
         case  AVMEDIA_TYPE_AUDIO:
                 output_codec_context->channel_layout = input_codec_context->channel_layout;
                 output_codec_context->sample_rate = input_codec_context->sample_rate;
                 output_codec_context->channels = input_codec_context->channels;
                 output_codec_context->frame_size = input_codec_context->frame_size;
                 if  ((input_codec_context->block_align == 1 && input_codec_context->codec_id == CODEC_ID_MP3) || input_codec_context->codec_id == CODEC_ID_AC3)
                 {
                         output_codec_context->block_align = 0;
                 }
                 else
                 {
                         output_codec_context->block_align = input_codec_context->block_align;
                 }
                 break ;
         case  AVMEDIA_TYPE_VIDEO:
                 output_codec_context->pix_fmt = input_codec_context->pix_fmt;
                 output_codec_context->width = input_codec_context->width;
                 output_codec_context->height = input_codec_context->height;
                 output_codec_context->has_b_frames = input_codec_context->has_b_frames;
                 if  (output_format_context->oformat->flags & AVFMT_GLOBALHEADER)
                 {
                         output_codec_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
                 }
                 break ;
         default :
                 break ;
         }
 
         return  output_stream;
}
 
int  _tmain( int  argc, _TCHAR* argv[])
{
 
         const  char * input =  "F:\\VideoPlayer\\debug\\StreamTotal.h264" ;
         const  char * output_prefix = NULL;
         char * segment_duration_check = 0;
         const  char * index = NULL;
         char * tmp_index = NULL;
         const  char * http_prefix = NULL;
         long  max_tsfiles = NULL;
         double  prev_segment_time = 0;
         double  segment_duration = 0;
         
         AVInputFormat* ifmt = NULL;
         AVOutputFormat* ofmt = NULL;
         AVFormatContext* ic = NULL;
         AVFormatContext* oc = NULL;
         AVStream* video_st = NULL;
         AVStream* audio_st = NULL;
         AVCodec* codec = NULL;
         AVDictionary* pAVDictionary = NULL;
 
         av_register_all();
 
         char  szError[256] = {0};
         int  nRet = avformat_open_input(&ic, input, ifmt, &pAVDictionary);
         if  (nRet != 0)
         {
                 av_strerror(nRet, szError, 256);
                 printf (szError);
                 printf ( "\n" );
                 printf ( "Call avformat_open_input function failed!\n" );
                 return  0;
         }
 
         if  (av_find_stream_info(ic) < 0)
         {
                 printf ( "Call av_find_stream_info function failed!\n" );
                 return  0;
         }
 
         ofmt = av_guess_format( "mpegts" , NULL, NULL);
         if  (!ofmt)
         {
                 printf ( "Call av_guess_format function failed!\n" );
                 return  0;
         }
 
         oc = avformat_alloc_context();
         if  (!oc)
         {
                 printf ( "Call av_guess_format function failed!\n" );
                 return  0;
         }
         oc->oformat = ofmt;
         
         int  video_index = -1, audio_index = -1;
         for  (unsigned  int  i = 0; i < ic->nb_streams && (video_index < 0 || audio_index < 0); i++)
         {
                 switch  (ic->streams[i]->codec->codec_type)
                 {
                 case  AVMEDIA_TYPE_VIDEO:
                         video_index = i;
                         ic->streams[i]->discard = AVDISCARD_NONE;
                         video_st = add_output_stream(oc, ic->streams[i]);
                         break ;
                 case  AVMEDIA_TYPE_AUDIO:
                         audio_index = i;
                         ic->streams[i]->discard = AVDISCARD_NONE;
                         audio_st = add_output_stream(oc, ic->streams[i]);
                         break ;
                 default :
                         ic->streams[i]->discard = AVDISCARD_ALL;
                         break ;
                 }
         }
         codec = avcodec_find_decoder(video_st->codec->codec_id);
         if  (codec == NULL)
         {
                 printf ( "Call avcodec_find_decoder function failed!\n" );
                 return  0;
         }
 
         if  (avcodec_open(video_st->codec, codec) < 0)
         {
                 printf ( "Call avcodec_open function failed !\n" );
                 return  0;
         }
 
         if  (avio_open(&oc->pb,  "F:\\VideoPlayer\\debug\\264.ts" , AVIO_FLAG_WRITE) < 0)
         {
                 return  0;
         }
 
         if  (avformat_write_header(oc, &pAVDictionary))
         {
                 printf ( "Call avformat_write_header function failed.\n" );
                 return  0;
         }
 
         int  decode_done = 0;
         do
         {
                 double  segment_time = 0;
                 AVPacket packet;
                 decode_done = av_read_frame(ic, &packet);
                 if  (decode_done < 0)
                         break ;
                         
                 if  (av_dup_packet(&packet) < 0)
                 {
                         printf ( "Call av_dup_packet function failed\n" );
                         av_free_packet(&packet);
                         break ;
                 }
 
                 if  (packet.stream_index == video_index && (packet.flags & AV_PKT_FLAG_KEY))
                 {
             segment_time = ( double )video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
         }
         else  if  (packet.stream_index == audio_index) {
             segment_time = ( double )audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
         }
         else  {
             segment_time = prev_segment_time;
         }
                 nRet = av_interleaved_write_frame(oc, &packet);
                 if  (nRet < 0)
                 {
                         printf ( "Call av_interleaved_write_frame function failed\n" );
                 }
                 else  if  (nRet > 0)
                 {
                         printf ( "End of stream requested\n" );
                         av_free_packet(&packet);
                         break ;
                 }
                 av_free_packet(&packet);
         } while (!decode_done);
 
         av_write_trailer(oc);
 
         av_bitstream_filter_close(bsfc);  
         avcodec_close(video_st->codec);
         for (unsigned  int  k = 0; k < oc->nb_streams; k++)
         {
                 av_freep(&oc->streams[k]->codec);
                 av_freep(&oc->streams[k]);
         }
         av_free(oc);
         getchar ();
         return  0;
}

你可能感兴趣的:(使用ffmpeg封装ts流的问题)