解码流程

  • 创捷解码器
  • 创建av_frame和av_packet
  • 解码 ```cpp

    include

using namespace std;

extern “C” {

include “libavcodec/avcodec.h”

include “libavutil/avutil.h”

include “libavutil/opt.h”

include “libavutil/channel_layout.h”

include “libavdevice/avdevice.h”

include “libswscale/swscale.h”

include “libswresample/swresample.h”

include “libavutil/samplefmt.h”

}

define V_WIDTH 640

define V_HEIGHT 480

/**

  • @brief xxxx
  • @param[in] width
  • @param[in] height
  • @return AVFrame / static AVFrame create_frame(int width, int height, AVPixelFormat pix_fmt) { int ret = 0; AVFrame frame = NULL;

    frame = av_frame_alloc(); if (!frame) {

    1. printf("Error, No Memory!\n");
    2. goto __ERROR;

    }

    //设置参数 frame->width = width; frame->height = height; frame->format = pix_fmt;

    //alloc inner memory ret = av_frame_get_buffer(frame, 32); //按32位对齐 【视频必须是32位对齐】 if (ret < 0) {

    1. printf("Error, Failed to alloc buffer for frame!\n");
    2. goto __ERROR;

    }

    return frame; __ERROR: if (frame) {

    1. av_frame_free(&frame);

    } return NULL; }

static int open_decoder(int width, int height, AVCodecContext* enc_ctx) { int ret = 0; AVCodec codec = NULL;

  1. codec = avcodec_find_decoder(AV_CODEC_ID_H264);
  2. if (!codec)
  3. {
  4. printf("Codec libx264 not found\n");
  5. exit(1);
  6. }
  7. *enc_ctx = avcodec_alloc_context3(codec);
  8. if (!enc_ctx)
  9. {
  10. printf("Counld out allocate video codec context\n\n");
  11. exit(1);
  12. }
  13. //设置分辨率
  14. (*enc_ctx)->width = width;
  15. (*enc_ctx)->height = height;
  16. //YUV格式
  17. (*enc_ctx)->pix_fmt = AV_PIX_FMT_YUV420P;
  18. ret = avcodec_open2((*enc_ctx), codec, NULL);
  19. if (ret < 0)
  20. {
  21. //printf("Counld not open codec: %s\n", av_err2str(ret));
  22. printf("Counld not open codec: %d\n", ret);
  23. exit(1);
  24. }

}

int main() { int ret = 0; const char out_filename = “yuv420.yuv”; string in_filename = “out.h264”; AVFormatContext fmt_ctx = NULL; AVPacket pkt = NULL; AVCodecContext codec_ctx = NULL; AVFrame frame = NULL; FILE yuv_outfile = NULL;

  1. yuv_outfile = fopen(out_filename, "wb+");
  2. ret = avformat_open_input(&fmt_ctx, in_filename.c_str(), NULL, NULL);
  3. if (ret != 0)
  4. {
  5. printf("ERROR, Failed to open file :%s!\n", in_filename.c_str());
  6. goto ERROR__;
  7. }
  8. //打开解码器
  9. open_decoder(V_WIDTH, V_HEIGHT, &codec_ctx);
  10. pkt = av_packet_alloc();
  11. av_init_packet(pkt);
  12. frame = create_frame(V_WIDTH, V_HEIGHT, AV_PIX_FMT_YUV420P);
  13. if (!frame)
  14. {
  15. printf("ERROR. Failed to create frame!\n");
  16. goto ERROR__;
  17. }
  18. while (!av_read_frame(fmt_ctx, pkt))
  19. {
  20. //av_parse_parse2();
  21. int ret = avcodec_send_packet(codec_ctx, pkt);
  22. if (ret < 0)
  23. {
  24. }
  25. while (ret >= 0)
  26. {
  27. ret = avcodec_receive_frame(codec_ctx, frame);
  28. //编码器数据不足时,返回EAGAIN,或者到数据结尾时返回AVERROR_EOF
  29. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
  30. break;
  31. if (ret < 0) {
  32. printf("error, failed to encode.\n");
  33. exit(1);
  34. }
  35. //outfile输出h264的编码
  36. fwrite(frame->data[0], 1, V_WIDTH*V_HEIGHT, yuv_outfile);
  37. fwrite(frame->data[1], 1, V_WIDTH*V_HEIGHT/4, yuv_outfile);
  38. fwrite(frame->data[2], 1, V_WIDTH*V_HEIGHT/4, yuv_outfile);
  39. }
  40. av_packet_unref(pkt);//减少newpkt的引用计数
  41. av_init_packet(pkt);
  42. }

ERROR__: if (frame) { av_frame_free(&frame); frame = NULL; } if (pkt) { av_packet_free(&pkt); pkt = NULL; } std::cout << “Hello World!\n”;

  1. return 0;

}

```