当前位置:   article > 正文

ffmpeg视频解码原理和实战-(1)对H264编码后的帧进行分割并存入AVPacket

ffmpeg视频解码原理和实战-(1)对H264编码后的帧进行分割并存入AVPacket

源文件:

  1. #include <iostream>
  2. #include <fstream>
  3. using namespace std;
  4. extern "C" { //指定函数是c语言函数,函数名不包含重载标注
  5. //引用ffmpeg头文件
  6. #include <libavcodec/avcodec.h>
  7. }
  8. //预处理指令导入库
  9. #pragma comment(lib,"avcodec.lib")
  10. #pragma comment(lib,"avutil.lib")
  11. int main(int argc, char* argv[])
  12. {
  13. //1 分割h264 存入AVPacket
  14. // ffmpeg -i v1080.mp4 -s 400x300 test.h264
  15. string filename = "test.h264";
  16. ifstream ifs(filename, ios::binary);
  17. if (!ifs)return -1;
  18. unsigned char inbuf[4096] = { 0 };
  19. AVCodecID codec_id = AV_CODEC_ID_H264;
  20. //1 找解码器
  21. auto codec = avcodec_find_decoder(codec_id);
  22. //2 创建上下文
  23. auto c = avcodec_alloc_context3(codec);
  24. //3 打开上下文
  25. avcodec_open2(c, NULL, NULL);
  26. //分割上下文
  27. auto parser = av_parser_init(codec_id);
  28. auto pkt = av_packet_alloc();
  29. while (!ifs.eof())
  30. {
  31. ifs.read((char*)inbuf, sizeof(inbuf));//将h264编码的流读入inbuf中
  32. int data_size = ifs.gcount();// 读取的字节数
  33. if (data_size <= 0)break;
  34. auto data = inbuf;
  35. while (data_size > 0) //一次有多帧数据
  36. {
  37. /* int av_parser_parse2(AVCodecParserContext * s,
  38. AVCodecContext * avctx,
  39. uint8_t * *poutbuf,
  40. int* poutbuf_size,
  41. const uint8_t * buf,
  42. int buf_size,
  43. int64_t pts,
  44. int64_t dts,
  45. int64_t pos);
  46. s :指向 AVCodecParserContext 的指针,用于维护解析器的状态。
  47. avctx : 指向 AVCodecContext 的指针,包含解码器的上下文信息。
  48. poutbuf : 输出缓冲区的指针,解析出的完整帧将被存储在这里。
  49. poutbuf_size : 输出缓冲区的大小,以字节为单位。
  50. buf : 输入缓冲区的指针,包含需要解析的原始数据。
  51. buf_size : 输入缓冲区的大小,以字节为单位。
  52. pts : 输入数据包的演示时间戳(presentation timestamp)。
  53. dts : 输入数据包的解码时间戳(decoding timestamp)。
  54. pos : 输入数据包在文件中的位置。*/
  55. //通过0001 截断输出到AVPacket 返回帧大小
  56. int ret = av_parser_parse2(parser, c,
  57. &pkt->data, &pkt->size, //输出
  58. data, data_size, //输入
  59. AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0
  60. );//返回消耗的输入数据字节数ret。如果所有输入数据都被消耗,则返回值等于 buf_size。如果解析过程中出现错误,则返回负数。
  61. data += ret;
  62. data_size -= ret; //待处理的数据大小
  63. if (pkt->size)
  64. {
  65. cout << pkt->size << " " << flush;
  66. }
  67. }
  68. }
  69. av_packet_free(&pkt);
  70. getchar();
  71. return 0;
  72. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/689168
推荐阅读
相关标签
  

闽ICP备14008679号