专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 多媒体/流媒体开发

使用ffmpeg封装ts流的有关问题

发布时间:2011-06-27 19:17:52 文章来源:www.iduyao.cn 采编人员:星星草
使用ffmpeg封装ts流的问题
各位好,我的问题是这样的。我有一个 h264编码的ES流视频文件,我想用ffmpeg来把视频文件封装成TS流。代码如下(部分代码来自网上,谢谢共享这份代码的网友)
C/C++ code
#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;
}
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: