当前位置: 代码迷 >> 多媒体/流媒体开发 >> 使用ffmpeg封装ts流的有关问题
  详细解决方案

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

热度:7034   发布时间:2013-02-26 00:00:00.0
使用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 __cplusplusextern "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 //__cplusplusstatic 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;}
  相关解决方案