免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 974 | 回复: 0
打印 上一主题 下一主题

csdn上大伙的同步讨论 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-02-24 10:53 |只看该作者 |倒序浏览
文件名用const char * 字符指针就行,赋值为一个“”引起的字符串。
文件用FILE结构体
打开文件用fopen,关闭文件用fclose,写入文件fwrite
ffmpeg也有自己的打开和关闭的函数
 
作者这个文章里头,分析的ffmpeg的那些代码的用意很好,比教程的分析好理解多了。
(1)读取(2)分离音频视频(3)解码(4)播放
作者在实践中发现了,ffmpeg采用队列来保存包的高明之处。
同步的问题,在这篇文章,没有得到解决。因为没谈及到同步的机制。
 
发帖人在这篇文章中,大量使用了ffmpeg的代码,这样可以节省很多时间。
作者好像是有pc端和下位机端的。
文件在pc端,读取出来文件以及文件的诸多信息之后,在下位机端解码。
音频和视频,是分别读取的,使用了两个不同的线程,下位机接受和解码也使用了两个线程。
 
作者没有交代如何显示的,但是肯定不是SDL,他用的是windows上的FFMPEG的SDK来做的。
作者现在亟待要解决的是同步的问题。
他用的是directshow。
====================
 
main(int argc, char *argv[])
{
AVFormatContext *pFormatCtx;
int i, videoStream;
int audioStream;
AVPacket packet;

FILE *hVideo;
FILE *hAudio;

const char *input_file_name = "F:\FFmpeg-full-SDK-3.2\res\src\2.ts";// 2.ts为采用h264和mp3编码的文件
const char *output_file_name = "F:\FFmpeg-full-SDK-3.2\res\dst\2.h264";
const char *output_file_name2 = "F:\FFmpeg-full-SDK-3.2\res\dst\2.mp3";

hVideo = fopen(output_file_name, "wb+");
if(hVideo == NULL)
{
return 0;
}

hAudio = fopen(output_file_name2, "wb+");
if(hAudio == NULL)
{
return 0;
}

// Register all formats and codecs
av_register_all();

// Open video file
if(av_open_input_file(&pFormatCtx, input_file_name, NULL, 0, NULL)!=0)
return -1;

// Retrieve stream information
if(av_find_stream_info(pFormatCtx) < 0)
return -1;

// Dump information about file onto standard error
dump_format(pFormatCtx, 0, input_file_name, false);

// Find the first video stream
videoStream = -1;
audioStream = -1;
for(i = 0; i < pFormatCtx->nb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
{
videoStream = i;
}
else if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
{
audioStream = i;
}
}
if(videoStream == -1)
{
return -1;
}

while(av_read_frame(pFormatCtx, &packet) >= 0)
{
if(packet.stream_index == videoStream)
{
int len;
len = fwrite(packet.data, 1, packet.size, hVideo);
//fwrite(&packet.pts, 1, sizeof(int64_t), hVideo);
}
else if(packet.stream_index == audioStream)
{
fwrite(packet.data, 1, packet.size, hAudio);
//fwrite(&packet.pts, 1, sizeof(int64_t), hAudio);
}

// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}

av_close_input_file(pFormatCtx);

fclose(hVideo);
fclose(hAudio);

return 0;
}

如上代码可以分离出视频和音频,但有个问题,我想把2.h264和2.mp3分别放到不同的线程进行播放(解码)。要如何才能保证2.h264文件和2.mp3文件同步播放呢。非常感谢!
</
Ffmpeg sdk中有详细的同步代码,你可以借见。

不同的文件做同步,肯定需要手动。
因为,起点不一样,至少需要手动去对齐。</
ffplay.c不就是个可以音视同步的播放器么</
首先感谢你们的回复,另上面代码,只是简单的把读取到的packet.data写到文件中,即fwrite(packet.data, 1, packet.size, hVideo); 我想问一下,packet中还有其他数据成员packet.pts,packet.dts 是否直接可以用来同步呢?谢谢!
</< p>

</
写包的时候pkt.pts就是控制同步的,这个必须弄对~</
谢谢各位!
另外,我需要对生成的音、视频文件分别加入时间戳信息。以便音视频文件在播放时,能进行同步
//ffmpeg中定义的结构体
typedef struct AVPacket {
    int64_t pts;                            /// < presentation time stamp in time_base units
    int64_t dts;                            /// < decompression time stamp in time_base units
    uint8_t *data;
    int  size;
    int  stream_index;
    int  flags;
    int  duration;                        /// < presentation duration in time_base units (0 if not available)
    void  (*destruct)(struct AVPacket *);
    void  *priv;
    int64_t pos;                            /// < byte position in stream, -1 if unknown
} AVPacket;

//自定义结构体
typedef struct tag_ASTREAM_S
{
  HI_U8  pABuffer[size1];
  HI_U64  pts;
  HI_U32  len;
}ASTREAM_S,*pASTREAM_S;

typedef struct tag_VSTREAM_S
{
  HI_U8  pVBuffer[size2];
  HI_U64  pts;
  HI_U32  len;
}VSTREAM_S,*pVSTREAM_S;

使用如上代码,当执行av_read_frame(pFormatCtx, &packet)后,把packet中的pts,size,data分别保存到视频结构体(或音频结构体)中,然后,在音、视频播放线程中,通过读取时间戳信息进行控制同步,但pABuffer[size1]和pVBuffer[size2]中的size1和size2要怎么确定?,从packet结构中获得的size会一直变化,而且很大。谢谢。</
参考ffplay的定义的结构,用的是队列~
你可以看看AVPacketList这个结构~</
typedef struct tag_VSTREAM_S
{
  HI_U8  pVBuffer[size2];
  HI_U64  pts;
  HI_U32  len;  // 这个长度是干嘛用的?
}VSTREAM_S,*pVSTREAM_S;

typedef struct tag_VSTREAM_S
{
  HI_U8*  pVBuffer; //用动态内存分配
  HI_U64  pts;
  HI_U32  bufferLen; 
}VSTREAM_S,*pVSTREAM_S;

可以参考TCP/IP 协议的处理。 </
有偿跪求基于directshow视频聊天程序,要求,基于directshow,视频可以单向传输,音频要求双向传输。传输前要压缩,有意者联系QQ 35265480 有偿啊,因为很着急

</
ffmpeg为了支持最多格式  只是用av_read_frame实现了个音视频同步的框架而已,但完全照他的方式  效果肯定不好 。  另外你为什么要dump出音视频文件再同步?  可以搞个缓冲区试试。 当然这是流媒体播放器的思路了  呵呵</
网上有教程,http://www.dranger.com/ffmpeg/tutorial05.html
这个教程是用ffmpeg+SDL来实现视音频的插放与同步,同步还是要用到AVPacket的PTS和DTS、</
一般有三种办法
1.以音频为主进行同步
2.以视频为主进行同步
3.以一个外部参考时钟为同步
你可以参考下ffmpeg下的ffplay来做,还有
http://www.dranger.com/ffmpeg/tutorial05.html 和
http://www.dranger.com/ffmpeg/tutorial04.html
具体如何实现还是要靠自己研究清楚代码后来解决的.</
我进来学习一下。

楼主在TS demux出来存成Video和Audio两个文件的时候,是不是应该把时间戳的信息也保存出来啊,不然的话单独只有一个audio和一个video的数据文件,同步从何谈起啊?</
<
mark</
谢谢各位的建议。


我把上面的while循环部分改成如下
while(av_read_frame(pFormatCtx, &packet) >= 0)
{
if(packet.stream_index == videoStream)
{
len = fwrite(&packet.pts , 1, 8, hVideo);
len = fwrite(&packet.size , 1, 4, hVideo);
len = fwrite(packet.data, 1, packet.size, hVideo);
}
else if(packet.stream_index == audioStream)
{
len = fwrite(&packet.pts, 1, 8, hAudio);
len = fwrite(&packet.size , 1, 4, hAudio);
len = fwrite(packet.data, 1, packet.size, hAudio);
}

// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
在代码中,当执行av_read_frame(pFormatCtx, &packet)后,我直接把packet中的pts保存到音频或视频文件中。但从packet获取到的pts值如下:
    视频pts值0 3600 7200 10800 …//按3600递增
    音频pts值0 2351 4702 7053  …//按2351递增

接下来,我把上面转出来的2.h264和2.mp3文件放在pc端,然后在pc端,用两个线程分别进行发送到下位机。PC端根据上面的pts值控制发送速度,采用以音频为主进行同步,当视频时间戳大于音频时间戳,则丢弃视频帧。而在下位机则用两个线程分别接收音频和视频,然后分别对音频和视频进行解码。但现在出现的问题是音视频能正常播放,但不能同步!我现在对获取到的音视频pts值特别不理解。没有达到控制音视频播放速度的效果,获取到的音频pts和视频pts怎么差别那么大?获取到的音视频pts能否直接比较?

附:
1.看了http://www.dranger.com/ffmpeg/tutorial05.html后,它是采用ffmpeg+SDL,看了晕乎乎。以前都没有接触过这方面的东西。

2.“ jinlking 兄弟的建议 pts *= av_q2d(is->video_st->time_base); 还要与一个基本的时间单位相乘”

这边av_q2d(is->video_st->time_base)后的值,
应该就是pFormatCtx->streams[videoStream]->time_base.num / pFormatCtx->streams[videoStream]->time_base.den吧?这样算出来的话,音视频都是1/90000吧 ?音视频都乘以这个time_base,跟没有乘以time_base效果是一样的,还是我的理解错了?
3.ffplay.c中的音视频同步代码,哪位兄弟能详细分析一下。

关于音视频同步问题,比较急,希望大家能帮帮我,再次谢谢大家。
</
由于时间比较急,没办法再去仔细研究音视频同步了,公司领导一直在催这个问题,如果哪位兄弟能具体说一下关于如何控制音视频同步问题,我自己来实现它,给予适当的报酬,表达一下心意也是可以的。谢谢。
我的邮箱:ljinchi@163.com
QQ:24385971</
关注,学习学习…

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP