博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[原]零基础学习视频解码之seek
阅读量:7195 次
发布时间:2019-06-29

本文共 24255 字,大约阅读时间需要 80 分钟。

现在,我们要添加一些功能,当你看不能倒带的电影,是不是很烦? 那么函数av_seek_frame功能看起来是多么赏心悦目。

我们将让左,右箭头来回走在影片中通过一个小的向上和向下箭头很多,其中“三多一少”是10秒,“很多”为60秒。因此,我们需要设置我们的主循环,用来捕获击键。然而,当我们得到一个按键,就不能直接称之为函数av_seek_frame。我们所要做的是在我们的主解码循环中,decode_thread循环做相应的处理。

为了检测按键,我们先来看看,看看我们得到了一个SDL_KEYDOWN事件。然后我们检查,看看哪个键得到使用event.key.keysym.sym。一旦我们知道我们要seek哪一种方式,我们通过增加增量,从我们的新get_master_clock函数值计算新的时间。接着我们调用stream_seek函数来设置seek_pos等值。我们新的时间转换为avcodec中的内部时间戳单元。回想一下,时间戳在流测量中的帧,而不是秒,于是秒=帧*time_base(fps)。 avcodec中默认为1,000,000 fps的值(这样的2秒的POS将是2000000时间戳)。

现在,让我们去到我们的decode_thread,我们将实际执行我们的seek。你会发现在我们已经标志着一个区域的源文件“seek的东西放在这里”,好了,我们打算把它放在那里了。

seek的函数av_seek_frame,该函数将seek到给它的时间戳。时间戳的单位是传递函数的流的基本time_base。但是,你不必把它传递一个流(通过传递值-1表示)。如果你这样做,那么time_base将是avcodec中的内部时间戳单位,或者1000000fps。这就是为什么当我们设置seek_pos乘AV_TIME_BASE。

av_rescale_q(A,B,C)是将重新调整时间戳从一个基地到另一个函数。它基本上是计算A * B/ C,但这个功能是必需的,因为计算可能溢出。 AV_TIME_BASE_Q是AV_TIME_BASE的小数版本。他们是完全不同的:AV_TIME_BASE* time_in_seconds= avcodec_timestamp和AV_TIME_BASE_Q* avcodec_timestamp= time_in_seconds(但要注意,AV_TIME_BASE_Q实际上是一个AVRational对象,所以你必须要使用特殊的q函数在avcodec中处理它)。

是的,但我们没有完成很呢。请记住,我们有一个队列设置了累积的数据包。现在,我们在不同的地方,我们要刷新的队列不是要去seek!不仅如此,avcodec中它自己内部的各缓冲器的需要由每个线程去刷新。

要做到这一点,我们需要先写一个函数来清除我们的数据包队列。然后,我们需要有指示音频和视频线,他们需要刷新avcodec中的内部缓冲器的一些方式。我们可以通过把一种特殊的数据包队列后,而当他们发现了特殊的包,他们就会刷新自己的缓冲区。

 

 

/* ============================================================================ Name        : VideoDecodeTutorial7_1.c Author      : clarck Version     : Copyright   : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */#include 
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef __MINGW32__#undef main /* Prevents SDL from overriding main() */#endif#include
#include
#define SDL_AUDIO_BUFFER_SIZE 1024#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)#define AV_SYNC_THRESHOLD 0.01#define AV_NOSYNC_THRESHOLD 10.0#define SAMPLE_CORRECTION_PERCENT_MAX 10#define AUDIO_DIFF_AVG_NB 20#define FF_ALLOC_EVENT (SDL_USEREVENT)#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)#define FF_QUIT_EVENT (SDL_USEREVENT + 2)#define VIDEO_PICTURE_QUEUE_SIZE 1#define DEFAULT_AV_SYNC_TYPE AV_SYNC_VIDEO_MASTER#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audiotypedef struct PacketQueue { AVPacketList *first_pkt, *last_pkt; int nb_packets; int size; SDL_mutex *mutex; SDL_cond *cond;} PacketQueue;typedef struct VideoPicture { SDL_Overlay *bmp; int width, height; /* source height & width */ int allocated; double pts;} VideoPicture;typedef struct VideoState { AVFormatContext *pFormatCtx; int videoStream, audioStream; int av_sync_type; double external_clock; /* external clock base */ int64_t external_clock_time; int seek_req; int seek_flags; int64_t seek_pos; double audio_clock; AVStream *audio_st; PacketQueue audioq; uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; unsigned int audio_buf_size; unsigned int audio_buf_index; AVPacket audio_pkt; uint8_t *audio_pkt_data; int audio_pkt_size; AVFrame audio_frame; AVStream *video_st; PacketQueue videoq; int audio_hw_buf_size; double audio_diff_cum; /* used for AV difference average computation */ double audio_diff_avg_coef; double audio_diff_threshold; int audio_diff_avg_count; double frame_timer; double frame_last_pts; double frame_last_delay; double video_current_pts; ///

 

转载地址:http://swtkm.baihongyu.com/

你可能感兴趣的文章
ionic3 打包发布,以安卓说明
查看>>
node.js 的 os 模块
查看>>
bzoj3223 文艺平衡树 codevs3303 翻转区间
查看>>
mysql中如何修改表的名字?修改表名?
查看>>
activemq入门实例
查看>>
C# ASE加密解密
查看>>
去掉"新建"出来的模板选择对话框
查看>>
简单的按月建立流水表类
查看>>
P3938 斐波那契
查看>>
dede织梦批量导入关键词
查看>>
iis6 服务器做301跳转返回状态码200解决方法。
查看>>
磁盘驱动的简单分析
查看>>
python 基础 8.2 编译正则对象
查看>>
centos7.2环境中kettle环境搭建及任务推送配置详解
查看>>
[译]理解 Windows UI 动画引擎
查看>>
【转载】CentOS日志系统组成详解
查看>>
题解 P1217 【[USACO1.5]回文质数 Prime Palindromes】
查看>>
TensorFlow从1到2(七)线性回归模型预测汽车油耗以及训练过程优化
查看>>
bzoj2959 长跑
查看>>
小知识点应用
查看>>