轉載:https://www.jianshu.com/p/3c95b0471d3a
1 // 不要用第四個參數傳自定的數據,當av_read_frame的時候會出問題,無限循環 2 avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, NULL, read_packet, NULL, NULL); 3 4 /* 5 avio_alloc_context開頭會讀取部分數據探測流的信息,不會全部讀取,除非設置的緩存過大 6 av_read_frame會在讀幀的時候調用avio_alloc_context中的read_packet方法取流數據,每隔avio_ctx_buffer_size調用一次,直至讀完 7 */
1 /*正確方式*/ 2 struct buffer_data 3 { 4 uint8_t *ptr; /* 文件中對應位置指針 */ 5 size_t size; ///< size left in the buffer /* 文件當前指針到末尾 */ 6 }; 7 8 // 重點,自定的buffer數據要在外面這里定義 9 struct buffer_data bd = {0}; 10 11 //用來將內存buffer的數據拷貝到buf 12 int read_packet(void *opaque, uint8_t *buf, int buf_size) 13 { 14 15 buf_size = FFMIN(buf_size, bd.size); 16 17 if (!buf_size) 18 return AVERROR_EOF; 19 printf("ptr:%p size:%zu bz%zu\n", bd.ptr, bd.size, buf_size); 20 21 /* copy internal buffer data to buf */ 22 memcpy(buf, bd.ptr, buf_size); 23 bd.ptr += buf_size; 24 bd.size -= buf_size; 25 26 return buf_size; 27 } 28 29 /* 打開前端傳來的視頻buffer */ 30 int open_input_buffer(uint8_t *buf, int len) 31 { 32 unsigned char *avio_ctx_buffer = NULL; 33 size_t avio_ctx_buffer_size = 32768; 34 35 AVInputFormat* in_fmt = av_find_input_format("h265"); 36 37 bd.ptr = buf; /* will be grown as needed by the realloc above */ 38 bd.size = len; /* no data at this point */ 39 40 fmt_ctx = avformat_alloc_context(); 41 42 avio_ctx_buffer = (unsigned char *)av_malloc(avio_ctx_buffer_size); 43 44 /* 讀內存數據 */ 45 avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, NULL, read_packet, NULL, NULL); 46 47 fmt_ctx->pb = avio_ctx; 48 fmt_ctx->flags = AVFMT_FLAG_CUSTOM_IO; 49 50 /* 打開內存緩存文件, and allocate format context */ 51 if (avformat_open_input(&fmt_ctx, "", in_fmt, NULL) < 0) 52 { 53 fprintf(stderr, "Could not open input\n"); 54 return -1; 55 } 56 return 0; 57 }