织梦CMS - 轻松建站从此开始!

罗索

spilit mpeg audio streams from mpeg2 ts stream

jackyhwei 发布于 2011-06-13 12:53 点击:次 
读取TS流文件并将其中的音频单独摘取出来的功能实现代码。
TAG:

读取TS流文件并将其中的音频单独摘取出来的功能实现代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int boolean;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;

#define FALSE 0
#define TRUE 1

#define MPEGTS_NORMAL_TS_PACKETSIZE 188
 
 
#define MAX_AUDIO_STREAM_NUM 256
 
typedef struct tagAudioStream
{
    FILE *fp;
    boolean started;
    uint16 pid;
}AudioStream;
 
static AudioStream audio_stream[MAX_AUDIO_STREAM_NUM] = {0};
 
void init_audio_stream()
{
    memset(audio_stream, 0, sizeof(AudioStream)*MAX_AUDIO_STREAM_NUM);
}
 
void uninit_audio_stream()
{
    int i=0;
    for(i=0; i<MAX_AUDIO_STREAM_NUM; i++)
    {
        if(audio_stream[i].fp != NULL)
            fclose(audio_stream[i].fp);
    }
}
 
AudioStream* new_stream(uint16 pid, boolean started)
{
    int i=0;
    for(i=0; i<MAX_AUDIO_STREAM_NUM; i++)
    {
        if(audio_stream[i].pid == pid)
        {
            if(audio_stream[i].started)
            {
                return audio_stream+i;
            }
            else if (started)
            {
                char name[32] = {0};
                sprintf(name, "%d.mp3", pid);
                audio_stream[i].fp = fopen(name, "wb");
 
                audio_stream[i].started = TRUE;
                return audio_stream+i;
            }
            return NULL;
        }
    }
    for(i=0; i<MAX_AUDIO_STREAM_NUM; i++)
    {
        if(audio_stream[i].pid == 0)
        {
            audio_stream[i].fp = NULL;
            audio_stream[i].pid = pid;
            if(started)
            {
                audio_stream[i].started = TRUE;
                return audio_stream+i;
            }
            else
            {
                audio_stream[i].started = FALSE;
                return  NULL;
            }
        }
    }  
    return NULL;    
}
 
void write_audio_stream(AudioStream *audio_stream, uint8* data, int data_len)
{
    if(audio_stream == NULL || data == NULL || data_len == 0)
        return;
    if(audio_stream->fp)  
    {
        fwrite(data, 1, data_len, audio_stream->fp);        
    }    
}
static int gst_pes_filter_parse (uint8 *in_data, int data_len)
{
    uint8 *data = in_data;
    int datalen = data_len;
    boolean have_size = FALSE;
    
    /* get start code */
    if((data[0] != 0x00) || (data[1] != 0x00) || (data[2] != 0x01) || (data[3] != 0xC0))
        return 0;
    
    /* skip start code and length */
    data += 6;
    datalen -= 6;
    
    /* stuffing bits, first two bits are '10' for mpeg2 pes so this code is
    * not triggered. */
    while (TRUE)  
    {
        if (*data != 0xff)
            break;
        
        datalen--;
    }
    
    /* STD buffer size, never for mpeg2 */
    if ((*data & 0xc0) == 0x40)  
    {
        data+=2;
        datalen -= 2;
    }
    
    /* PTS but no DTS, never for mpeg2 */
    if ((*data & 0xf0) == 0x20)  
    {
        data+=5;
        datalen -= 5;
    }
    /* PTS and DTS, never for mpeg2 */
    else if ((*data & 0xf0) == 0x30)  
    {
        data +=10;
        datalen -= 10;
    }  
    else if ((*data & 0xc0) == 0x80)  
    {
        /* mpeg2 case */
        uint8 flags;
        uint8 header_data_length = 0;
        
        flags = *data++;
 
        flags = *data++;
        
        /* 8: PES_header_data_length */
        header_data_length = *data++;
        datalen -= 3;
 
        /* only DTS: this is invalid */
        if ((flags & 0xc0) == 0x40)
            return 0;
        
        /* check for PTS */
        if ((flags & 0x80))  
        {
            header_data_length -= 5;
            datalen -= 5;
        }
        /* check for DTS */
        if ((flags & 0x40))  
        {
            header_data_length -= 5;
            datalen -= 5;
        }
        /* ESCR_flag */
        if ((flags & 0x20))  
        {
            data += 6;
            header_data_length -= 6;
            datalen -= 6;
        }
        /* ES_rate_flag */
        if ((flags & 0x10))  
        {
            data += 3;
            header_data_length -= 3;
            datalen -= 3;
        }
        /* DSM_trick_mode_flag */
        if ((flags & 0x08))  
        {
            data += 1;
            header_data_length -= 1;
            datalen -= 1;
        }
 
        /* PES_extension_flag  */
        if ((flags & 0x01))  
        {
            flags = *data++;
            header_data_length -= 1;
            datalen -= 1;
            if ((flags & 0x80))
            {
                data += 16;
                header_data_length -= 16;
                datalen -= 16;
            }
            /* pack_header_field_flag */
            if ((flags & 0x40))
            {
                uint8 pack_field_length = *data;
                data += pack_field_length + 1;
                header_data_length -= pack_field_length + 1;
                datalen -= pack_field_length + 1;
            }
            /* program_packet_sequence_counter_flag */
            if ((flags & 0x20))  
            {
                data += 2;
                header_data_length -= 2;
                datalen -= 2;
            }
            /* P-STD_buffer_flag */
            if ((flags & 0x10))  
            {
                data += 2;
                header_data_length -= 2;
                datalen -= 2;
            }
            /* PES_extension_flag_2 */
            if ((flags & 0x01))  
            {
                uint8 PES_extension_field_length = *data++;
                data += PES_extension_field_length & 0x7f;
                header_data_length -= (PES_extension_field_length & 0x7f) + 1;
                datalen -= (PES_extension_field_length & 0x7f) + 1;
            }
        }
        /* calculate the amount of real data in this PES packet */
        data += header_data_length;
        datalen -= header_data_length;
    }  
    else if (*data == 0x0f)  
    {
      /* Not sure what this clause is for */
      data++;
      datalen--;
    }  
    else  
    {
        return 0;
    }
    return datalen;
}

void parse_ts_packet(uint8 *in_data)
{
    uint16 PID;
    boolean payload_unit_start_indicator;
    const uint8 *data = in_data;
    uint32 datalen = MPEGTS_NORMAL_TS_PACKETSIZE;
    AudioStream *audio_stream = NULL;
    
    PID = ((data[1] & 0x1f) << 8) | data[2];
    if(PID == 0x1FFF)
    {
        return;
    }
    payload_unit_start_indicator = (data[1] & 0x40) == 0x40;
    if(payload_unit_start_indicator)
    {
        int left_len = gst_pes_filter_parse(data+0x4, 0xB8);
        if(left_len)
        {
            audio_stream = new_stream(PID, payload_unit_start_indicator);
            write_audio_stream(audio_stream, data+MPEGTS_NORMAL_TS_PACKETSIZE-left_len, left_len);
        }
    }
    else
    {
        audio_stream = new_stream(PID, FALSE);
        write_audio_stream(audio_stream, data+0x4, 0xB8);
    }
}
 
int main()
{
    uint8 buffer[MPEGTS_NORMAL_TS_PACKETSIZE] = {0};
    FILE *fp = NULL;
    fp = fopen("d:\\wang.ts", "rb");
    if(fp == NULL)
    {
        return  0;
    }
    init_audio_stream();
    while(MPEGTS_NORMAL_TS_PACKETSIZE == fread(buffer, 1, MPEGTS_NORMAL_TS_PACKETSIZE, fp))
    {
        parse_ts_packet(buffer);
    }
    uninit_audio_stream();
    fclose(fp);
    return 0;
}

(carlsonlee_freec)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201106/14553.html]
本文出处:百度博客 作者:carlsonlee_freec
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容