#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;
}