日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AVIO内存输入模式

發布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AVIO内存输入模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

AVIO內存輸入模式


目錄

  • 介紹
  • 代碼示例

  • 1. 介紹

  • AVIO內存輸入模式是將內存區作輸入輸出,當啟用內存IO模式后(即ifmt_ctx->pb有效時),將會忽略avformat_open_input()第二個參數url的值。
  • 而對于其他一些場合,當有效音視頻數據位于內存,而這片內存并無一個URL屬性可用時,則只能使用內存IO模式來取得輸入數據。

  • 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内存输入模式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。