ffmpeg学习笔记(2)

2019-08-29 19:56

18. return 0; 19. } 20.

21. //一般会执行到这里

22. if ((s->iformat && s->iformat->flags & AVFMT_NOFILE)

23. || (!s->iformat && (s->iformat = av_probe_input_format(&pd, 0)))

)

24. //如果已指定了iformat并且不需要文件,也就不需要pb了,可以直接返回 25. //如果没指定iformat,但是可以从文件名中猜出iformat,也成功. 26. return 0; 27.

28. //如果从文件名中也猜不出媒体格式,则只能打开这个文件进行探测了,先打开文件 29. if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0) 30. return ret; 31. if (s->iformat) 32. return 0; 33. //再探测之

34. return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0); 35. }

avio_open

[cpp] view plaincopy

1. //打开一个地址指向的媒体

2. int avio_open(AVIOContext **s, const char *filename, int flags) 3. {

4. //URLContext代表一个URL地址指向的媒体文件,本地路径也算一种.它封装了 5. //操作一个媒体文件的相关数据,最重要的是prot变量,是URLProtocol型的. 6. //prot代表一个特定的协义和协议操作函数们,URLContext包含不同的prot, 7. //就可以通过URLContext使用不同的协议读写媒体数据,比如tcp,http,本地 8. //文件用file协议. 9. URLContext *h; 10. int err; 11.

12. //创建并初始化URLContext,其prot通过文件名确定.然后打开这个媒体文件 13. err = ffurl_open(&h, filename, flags); 14. if (err < 0) 15. return err;

16. //其实文件已经在上边真正打开了.这里只是填充AVIOContext.使它记录下 17. //URLContext,以及填充读写数据的函数指针. 18. err = ffio_fdopen(s, h); 19. if (err < 0) {

20. ffurl_close(h); 21. return err; 22. }

23. return 0; 24. }

av_probe_input_buffer

[cpp] view plaincopy

1. int av_probe_input_buffer(AVIOContext *pb, 2. AVInputFormat **fmt, 3. const char *filename, 4. void *logctx, 5. unsigned int offset,

6. unsigned int max_probe_size) 7. {

8. AVProbeData pd = { filename ? filename : \, NULL, -offset }; 9. unsigned char *buf = NULL; 10. int ret = 0, probe_size; 11.

12. //计算最多探测数据的字节数 13. if (!max_probe_size) {

14. max_probe_size = PROBE_BUF_MAX;

15. } else if (max_probe_size > PROBE_BUF_MAX) { 16. max_probe_size = PROBE_BUF_MAX;

17. } else if (max_probe_size < PROBE_BUF_MIN) { 18. return AVERROR(EINVAL); 19. } 20.

21. if (offset >= max_probe_size) { 22. return AVERROR(EINVAL); 23. } 24.

25. //循环直到探测完指定的数据

26. for (probe_size = PROBE_BUF_MIN;

27. probe_size <= max_probe_size && !*fmt; 28. probe_size =

29. FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1)

)) {

30. int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX / 4 : 0;

31. int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size >> 1

;

32. void *buftmp; 33.

34. if (probe_size < offset) { 35. continue; 36. } 37.

38. /* read probe data */ 39. //分配读取数据存放的缓冲

40. buftmp = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE); 41. if (!buftmp) { 42. av_free(buf);

43. return AVERROR(ENOMEM); 44. }

45. buf = buftmp;

46. //利用pb读数据到缓冲的剩余空间中

47. if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset))

48. < 0) {

49. /* fail if error was not end of file, otherwise, lower score */

50. if (ret != AVERROR_EOF) { 51. av_free(buf); 52. return ret; 53. }

54. score = 0;

55. ret = 0; /* error was end of file, nothing read */ 56. }

57. pd.buf_size += ret; 58. pd.buf = &buf[offset]; 59.

60. //缓冲中没有数据的部分要清0

61. memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); 62.

63. /* guess file format */ 64. //从一个打开的文件只探测媒体格式

65. *fmt = av_probe_input_format2(&pd, 1, &score); 66. if (*fmt) {

67. if (score <= AVPROBE_SCORE_MAX / 4) { //this can only be true in

the last iteration 68. av_log(

69. logctx,

70. AV_LOG_WARNING,

71. \

tection possible!\\n\,

72. (*fmt)->name, score); 73. } else

74. av_log(logctx, AV_LOG_DEBUG,

75. \, 76. (*fmt)->name, probe_size, score); 77. }

78. //不成功,继续 79. } 80.

81. if (!*fmt) { 82. av_free(buf);

83. return AVERROR_INVALIDDATA; 84. } 85.

86. /* rewind. reuse probe buffer to avoid seeking */ 87. //把探测时读入的数据保存到pb中,为的是真正读时直接利用之.

88. if ((ret = ffio_rewind_with_probe_data(pb, buf, pd.buf_size)) < 0) 89. av_free(buf); 90.

91. return ret; 92. }

7.获取流信息

int videoStreamIndex = 0;

for (; videoStreamIndex < pFormatCtx->nb_streams; ++videoStreamIndex) { }

if (videoStreamIndex == pFormatCtx->nb_streams) { }

//没有找到视频流 abort();

if (pFormatCtx->streams[videoStreamIndex]->codec->coder_type == { }

break;

AVMEDIA_TYPE_VIDEO)

8.解码视频

AVCodecContext *pCodeCtx =

pFormatCtx->streams[videoStreamIndex]->codec;

//获?取¨?解a码?器??

AVCodec * pCodec = avcodec_find_decoder(pCodeCtx->codec_id); if (pCodec == NULL) { }

if (pCodec->capabilities & CODEC_CAP_TRUNCATED) { }

if (avcodec_open2(pCodeCtx,pCodec,NULL)<0) { }

//给解码后视频帧预分配存储空间? AVFrame *pFrame = NULL;

pFrame = avcodec_alloc_frame(); //预分配存储空间用来存储转换后的帧? AVFrame *pFrameRGB = NULL;

pFrameRGB = avcodec_alloc_frame();

int numBytes = avpicture_get_size(PIX_FMT_RGB24,

abort();

pCodeCtx->flags |= CODEC_FLAG_TRUNCATED; abort();

pCodeCtx->width,pCodeCtx->height);

//指向的内存关联起来

uint8_t *buffer = (uint8_t*)av_malloc(numBytes); avpicture_fill( (AVPicture *)pFrameRGB, buffer,

PIX_FMT_RGB24,pCodeCtx->width, pCodeCtx->height);

AVPacket pPacket; int num = 0;

char *fileEx = \;

while(av_read_frame(pFormatCtx,&pPacket)>=0) {

//判断是否为视频流

if (pPacket.stream_index == videoStreamIndex) {

int decFinished;

avcodec_decode_video2(pCodeCtx,pFrame,&decFinished,&pPacket); if (decFinished) {

struct SwsContext * img_convert_ctx = NULL;


ffmpeg学习笔记(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:高职考试英语模拟试卷

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: