Skip to content

Instantly share code, notes, and snippets.

@Neko3000
Last active October 28, 2020 01:21
Show Gist options
  • Save Neko3000/622d9d27afca0a93bb296615e1eea5e9 to your computer and use it in GitHub Desktop.
Save Neko3000/622d9d27afca0a93bb296615e1eea5e9 to your computer and use it in GitHub Desktop.
/**
* Open an input stream and read the header. The codecs are not opened.
* The stream must be closed with avformat_close_input().
*
* @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
* May be a pointer to NULL, in which case an AVFormatContext is allocated by this
* function and written into ps.
* Note that a user-supplied AVFormatContext will be freed on failure.
* @param url URL of the stream to open.
* @param fmt If non-NULL, this parameter forces a specific input format.
* Otherwise the format is autodetected.
* @param options A dictionary filled with AVFormatContext and demuxer-private options.
* On return this parameter will be destroyed and replaced with a dict containing
* options that were not found. May be NULL.
*
* @return 0 on success, a negative AVERROR on failure.
*
* @note If you want to use custom IO, preallocate the format context and set its pb field.
*/
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);
- (void)run{
self.onPacketBufferFullBlock = ^(){
};
self.onPacketBufferEmptyBlock = ^(){
};
[self prepareToRead];
[self readPacket];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
self.second = 0;
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
- (void)onTimer{
// 每过3秒消耗一次数据包
// 随机决定“消耗一个数据包”还是“消耗所有数据包”
if(self.second % 3 == 0){
int randomNumber = arc4random_uniform(2);
if(randomNumber == 0){
// 消耗所有数据包
av_packet_queue_flush(&audioq);
av_packet_queue_flush(&videoq);
self.packetBufferIsFull = NO;
self.packetBufferIsEmpty = YES;
NSLog(@"# %ds - comsume all packets,now audioq = %d, videoq = %d", (int)self.second, audioq.nb_packets, videoq.nb_packets);
}
else{
// 消耗一个数据包
AVPacket audioPkt;
int audioqNotEmpty = av_packet_queue_get(&audioq, &audioPkt, 0);
if(audioqNotEmpty){
av_packet_unref(&audioPkt);
}
AVPacket videoPkt;
int videoqNotEmpty = av_packet_queue_get(&videoq, &videoPkt, 0);
if(videoqNotEmpty){
av_packet_unref(&videoPkt);
}
self.packetBufferIsFull = NO;
if(!audioqNotEmpty && !videoqNotEmpty){
self.packetBufferIsEmpty = YES;
}
NSLog(@"# %ds - comsume one packet, now audioq = %d, videoq = %d", (int)self.second, audioq.nb_packets, videoq.nb_packets);
}
}
else{
NSLog(@"# %ds - packet buffer is %@full, now audioq = %d, videoq = %d",(int)self.second, self.packetBufferIsFull ? @"":@"not ", audioq.nb_packets, videoq.nb_packets);
}
self.second += 1;
}
ret = av_read_frame(ic, pkt);
if (ret < 0) {
if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
if (is->video_stream >= 0)
packet_queue_put_nullpacket(&is->videoq, is->video_stream);
if (is->audio_stream >= 0)
packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
if (is->subtitle_stream >= 0)
packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
is->eof = 1;
}
if (ic->pb && ic->pb->error) {
if (autoexit)
goto fail;
else
break;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment