AVIO内存输入模式
生活随笔
收集整理的這篇文章主要介紹了
AVIO内存输入模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
AVIO內存輸入模式
目錄
1. 介紹
2. 代碼示例
#include <stdio.h> #include <stdlib.h> #include <string.h>#include <libavutil/frame.h> #include <libavutil/mem.h>#include <libavcodec/avcodec.h> #include <libavformat/avformat.h>#define BUF_SIZE 20480static char *av_get_err(int errnum) {static char err_buf[128] = {0};av_strerror(errnum, err_buf, 128);return err_buf; }static void decode(AVCodecContext *dec_ctx, AVPacket *packet, AVFrame *frame, FILE *outfile) {int ret = 0;ret = avcodec_send_packet(dec_ctx, packet);if (ret == AVERROR(EAGAIN)) {printf("Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");} else if (ret < 0) {printf("Error submitting the packet to the decoder, err:%s\n",av_get_err(ret));return;}while (ret >= 0) {ret = avcodec_receive_frame(dec_ctx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {return;} else if (ret < 0) {printf("Error during decoding\n");exit(1);}if (!packet) {printf("get flush frame\n");}int data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);/**P表示Planar(平面),其數據格式排列方式為 :LLLLLLRRRRRRLLLLLLRRRRRRLLLLLLRRRRRRL...(每個LLLLLLRRRRRR為一個音頻幀)而不帶P的數據格式(即交錯排列)排列方式為:LRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLRL...(每個LR為一個音頻樣本)播放范例: ffplay -ar 48000 -ac 2 -f f32le believe.pcm并不是每一種都是這樣的格式*/// 這里的寫法不是通用,通用要調用重采樣的函數去實現// 這里只是針對解碼出來是planar格式的轉換for (int i = 0; i < frame->nb_samples; i++) {for (int ch = 0; ch < dec_ctx->channels; ch++) {fwrite(frame->data[ch] + data_size * i, 1, data_size, outfile);}}} }static int read_packet(void *opaque, uint8_t *buf, int buf_size) {FILE *in_file = (FILE *) opaque;int read_size = fread(buf, 1, buf_size, in_file);printf("read_packet read_size:%d, buf_size:%d\n", read_size, buf_size);if (read_size <= 0) {return AVERROR_EOF; // 數據讀取完畢}return read_size; }int main(int argc, char **argv) {if(argc != 3) {printf("usage: %s <intput file> <out file>\n", argv[0]);return -1;}const char *in_file_name = argv[1];const char *out_file_name = argv[2];// const char *in_file_name = "/Users/lijinwang/Downloads/course/study/believe.aac"; // const char *out_file_name = "/Users/lijinwang/Downloads/course/study/believe4.pcm";FILE *in_file = NULL;FILE *out_file = NULL;//1. 打開參數文件in_file = fopen(in_file_name, "rb");if (!in_file) {printf("open file %s failed\n", in_file_name);return -1;}out_file = fopen(out_file_name, "wb");if (!out_file) {printf("open file %s failed\n", out_file_name);return -1;}uint8_t *io_buffer = av_malloc(BUF_SIZE);AVIOContext *avio_ctx = (io_buffer, BUF_SIZE, 0, (void *) in_file, read_packet, NULL, NULL);AVFormatContext *format_ctx = avformat_alloc_context();format_ctx->pb = avio_ctx;int ret = avformat_open_input(&format_ctx, NULL, NULL, NULL);if (ret < 0) {printf("avformat_open_input failed:%s\n", av_err2str(ret));return -1;}//編碼器查找AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_AAC);if (!codec) {printf("avcodec_find_decoder failed\n");return -1;}AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);if (!codec_ctx) {printf("avcodec_alloc_context3 failed\n");return -1;}ret = avcodec_open2(codec_ctx, codec, NULL);if (ret < 0) {printf("avcodec_open2 failed:%s\n", av_err2str(ret));return -1;}AVPacket *packet = av_packet_alloc();AVFrame *frame = av_frame_alloc();while (1) {ret = av_read_frame(format_ctx, packet);if (ret < 0) {printf("av_read_frame failed:%s\n", av_err2str(ret));break;}decode(codec_ctx, packet, frame, out_file);}printf("read file finish\n");decode(codec_ctx,packet,frame,out_file);fclose(in_file);fclose(out_file);av_free(io_buffer);av_frame_free(frame);av_packet_free(packet);avformat_close_input(&format_ctx);avcodec_free_context(&codec_ctx);return 0; }總結
以上是生活随笔為你收集整理的AVIO内存输入模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 音频解码和视频解码
- 下一篇: 音频处理基本概念及音频重采样