📄 audio_stream.c
字号:
}
if(ps->stream_id == 0){
return 0;
}
extract_pes_packet_data(&packet, buffer, &pos);
while(read_pes_packet_ps(ps->bs, &packet)){
if(pos > 64*1024){
break;
}
if(bs_tell(ps->bs) > 8*1024*1024){
break;
}
if(packet.stream_id == ps->stream_id){
extract_pes_packet_data(&packet, buffer+pos, &n);
pos += n;
}
}
p = buffer;
last = p+pos-3;
n = 0;
while(p < last){
if( (p[0] == 0xff) && ((p[1] & 0xf0) == 0xf0) ){
sync = ((unsigned int)(p[0]) << 24) | ((unsigned int)(p[1]) << 16) | ((unsigned int)(p[2]) << 8) | p[3];
if( ! parse_layer2_header(sync, &hd) ){
p += 1;
n = 0;
continue;
}
if( p + hd.framesize >= last ){
break;
}
if( (p[hd.framesize] == 0xff) && ((p[hd.framesize+1] & 0xf0) == 0xf0) ){
n += 1;
p += hd.framesize;
}else{
p += 1;
n = 0;
}
}else{
p += 1;
n = 0;
}
}
if(n == 0){
return 0;
}
ps->frequency = hd.frequency;
ps->channel = hd.channel;
return 1;
}
static int set_start_pts_ps(AUDIO_PS *ps)
{
__int64 audio_start_pts;
__int64 video_start_pts;
__int64 video_pts[3];
PTS_DTS pts_dts;
PES_PACKET packet;
PES_STREAM_TYPE type;
unsigned char *buffer;
unsigned char *pos;
unsigned char *last;
int n;
int closed_gop;
int video_id;
buffer = (unsigned char *)malloc(8*1024*1024);
if(buffer == NULL){
return 0;
}
init_pes_packet(&packet);
pos = buffer;
last = buffer;
bs_seek(ps->bs, 0, SEEK_SET);
video_id = 0;
audio_start_pts = -1;
video_start_pts = -1;
video_pts[0] = -1;
video_pts[1] = -1;
video_pts[2] = -1;
closed_gop = 0;
while(read_pes_packet_ps(ps->bs, &packet)){
if(extract_pes_stream_type(&packet, &type)){
if(packet.stream_id == ps->stream_id){
if(audio_start_pts < 0){
extract_pes_pts_dts(&packet, &pts_dts);
audio_start_pts = pts_dts.pts;
}
}else if(type.type == PES_STREAM_TYPE_VIDEO){
if(video_id == 0){
video_id = type.id;
}else if(video_id != type.id){
continue;
}
if(video_start_pts < 0){
extract_pes_pts_dts(&packet, &pts_dts);
extract_pes_packet_data(&packet, last, &n);
last += n;
if(pts_dts.pts >= 0){
if(video_pts[0] < 0){
video_pts[0] = pts_dts.pts;
}else{
video_pts[1] = pts_dts.pts;
}
}
while( (pos = find_next_001(pos, last)) != NULL ){
if(pos+3>=last){
break;
}
if(pos[3] == 0xb8){
if(pos+7<last){
closed_gop = (pos[7] >> 6) & 1;
pos += 7;
}else{
break;
}
}else if(pos[3] == 0x00){
if(pos+5<last){
int type = (pos[5]>>3) & 7;
if(type == 1){
if(!closed_gop){
video_start_pts = video_pts[0];
break;
}else{
video_pts[2] = video_pts[0];
if(video_pts[1] >= 0){
video_pts[0] = video_pts[1];
video_pts[1] = -1;
}else{
video_pts[0] = -1;
}
}
}else if(type == 2){
if(video_pts[2] >= 0){
video_start_pts = video_pts[2];
break;
}else{
if(video_pts[1] >= 0){
video_pts[0] = video_pts[1];
video_pts[1] = -1;
}else{
video_pts[0] = -1;
}
}
}else if(type == 3){
if(video_pts[2] >= 0){
video_start_pts = video_pts[0];
break;
}else{
if(video_pts[1] >= 0){
video_pts[0] = video_pts[1];
video_pts[1] = -1;
}else{
video_pts[0] = -1;
}
}
}
pos += 5;
}else{
break;
}
}else{
pos += 3;
}
}
if(pos == NULL){
pos = last-2;
}
}
}
}
if( (audio_start_pts >= 0) && (video_start_pts >= 0) ){
break;
}
if(bs_tell(ps->bs) > 8*1024*1024){
break;
}
}
free(buffer);
release_pes_packet(&packet);
if( (video_start_pts >= 0) && (audio_start_pts >= 0) ){
ps->pts[0].back_pts = video_start_pts;
}else{
ps->pts[0].back_pts = audio_start_pts;
}
if(ps->pts[0].back_pts < 0){
return 0;
}
return 1;
}
static int set_filesize_and_sample_ps(AUDIO_PS *ps)
{
int i,n;
n = ps->bs->mf->count(ps->bs->mf);
for(i=0;i<n;i++){
if(!set_unit_pts_ps(ps, i)){
return 0;
}
}
ps->filesize = ps->bs->mf->border(ps->bs->mf, n-1);
ps->sample = pts_to_sample(ps->pts[n].face_pts, ps->frequency);
return 1;
}
static int set_unit_pts_ps(AUDIO_PS *ps, int unit)
{
__int64 offset;
__int64 sample;
PTS_DTS pts_dts;
PES_PACKET packet;
int r;
int count;
bs_seek(ps->bs, ps->bs->mf->border(ps->bs->mf, unit), SEEK_SET);
init_pes_packet(&packet);
r = 0;
count = 0;
while(bs_prev_packet_prefix(ps->bs)){
if( (bs_read_bits(ps->bs, 32)) == 0x100 + ps->stream_id){
offset = bs_tell(ps->bs);
if(read_pes_packet_ps(ps->bs, &packet)){
extract_pes_pts_dts(&packet, &pts_dts);
if(pts_dts.pts >= 0){
sample = count_audio_frame(&packet) * 1152;
if(sample == 0){
/* stream has probrem
* pes packet contains no audio access unit head byte
* and pes packet has pts
*/
count+=1;
if(count > 4){
ps->pts[unit+1].face_pts = pts_dts.pts;
break;
}
bs_seek(ps->bs, offset-4, SEEK_SET);
continue;
}
ps->pts[unit+1].face_pts = pts_dts.pts - ps->pts[unit].back_pts + ps->pts[unit].face_pts;
ps->pts[unit+1].face_pts += sample_to_pts(sample, ps->frequency);
r = 1;
break;
}else{
bs_seek(ps->bs, offset-4, SEEK_SET);
}
}else{
bs_seek(ps->bs, offset-4, SEEK_SET);
}
}else{
ps->bs->current -= 4;
}
}
if(pts_dts.pts < 0){
release_pes_packet(&packet);
return 0;
}
bs_seek(ps->bs, ps->bs->mf->border(ps->bs->mf, unit), SEEK_SET);
while(read_pes_packet_ps(ps->bs, &packet)){
if(packet.stream_id == ps->stream_id){
extract_pes_pts_dts(&packet, &pts_dts);
if(pts_dts.pts >= 0){
ps->pts[unit+1].back_pts = pts_dts.pts;
break;
}
}
}
offset = ps->pts[unit+1].face_pts - ps->pts[unit].face_pts;
offset -= ps->pts[unit+1].back_pts - ps->pts[unit].back_pts;
if(offset < 0){
offset = 0 - offset;
}
if(offset < 450){ /* under 5 msec */
ps->pts[unit+1].face_pts = ps->pts[unit+1].back_pts - ps->pts[unit].back_pts + ps->pts[unit].face_pts;
}
release_pes_packet(&packet);
return r;
}
static int read_pes_packet_ps(BITSTREAM *in, PES_PACKET *out)
{
int code, n, m;
unsigned char buf[6];
do{
if(! bs_next_packet_prefix(in)){
return 0;
}
code = bs_get_bits(in, 32);
}while(code < 0x1bc);
release_pes_packet(out);
buf[0] = 0;
buf[1] = 0;
buf[2] = 1;
buf[3] = (unsigned char)( code & 0xff );
n = bs_get_bits(in, 16);
buf[4] = (unsigned char)( (n >> 8) & 0xff );
buf[5] = (unsigned char)( n & 0xff );
append_pes_packet_data(out, buf, sizeof(buf));
while(n){
m = bs_read(in, out->data+out->size, n);
n -= m;
out->size += m;
if(m == 0){
return 0;
}
}
return out->size;
}
static __int64 pts_to_sample(__int64 pts, int rate)
{
__int64 sec;
__int64 mod;
sec = pts/90000;
mod = pts%90000;
return (sec*rate+(mod*rate/90000));
}
static __int64 sample_to_pts(__int64 sample, int rate)
{
__int64 sec;
__int64 mod;
sec = sample / rate;
mod = sample % rate;
return (sec*90000+(mod*90000/rate));
}
static int count_audio_frame(PES_PACKET *packet)
{
int r;
int n;
unsigned int sync;
unsigned char *pos;
unsigned char *last;
LAYER2_HEADER head;
n = get_pes_packet_data_length(packet);
pos = packet->data+packet->size-n;
last = pos+n-3;
r = 0;
while(pos<last){
if( (pos[0] == 0xff) && ((pos[1] & 0xf0) == 0xf0) ){
sync = ((unsigned int)(pos[0]) << 24) | ((unsigned int)(pos[1]) << 16) | ((unsigned int)(pos[2]) << 8) | ((unsigned int)(pos[3]));
if(! parse_layer2_header(sync, &head)){
pos += 1;
continue;
}
if( pos+head.framesize >= last ){
break;
}
if( (pos[head.framesize] == 0xff) && ((pos[head.framesize+1] & 0xf0) == 0xf0) ){
r += 1;
pos += head.framesize;
}else{
pos += 1;
}
}else{
pos += 1;
}
}
if(pos != last){
r += 1;
}
return r;
}
static unsigned char *find_sync_current_ps_buffer(AUDIO_PS *ps)
{
unsigned char *pos;
unsigned char *last;
unsigned int sync;
LAYER2_HEADER h;
last = ps->buffer.buffer+ps->buffer.size;
while( (pos = mb_next_fff(&(ps->buffer))) != NULL ){
if(pos+4 >= last ){
break;
}
sync = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) | pos[3];
if(parse_layer2_header(sync, &h)){
if( pos+h.framesize == last ){
return pos;
}
if( pos+h.framesize+1 >= last ){
break;
}
if( (pos[h.framesize] == 0xff) && ((pos[h.framesize+1] & 0xf0) == 0xf0) ){
return pos;
}
}
ps->buffer.pos += 1;
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -