avio_alloc_context中的callback通过fifo读取 怎么改写给个示例
时间: 2024-03-09 17:48:35 浏览: 86
如果你想改写 `avio_alloc_context` 中的 callback 函数,使它通过其他方式读取数据而非 fifo,可以参考下面的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavformat/avformat.h>
#define BUFFER_SIZE 4096
typedef struct {
uint8_t *data;
int size;
int pos;
} Buffer;
int read_packet(void *opaque, uint8_t *buf, int buf_size) {
Buffer *buffer = (Buffer *)opaque;
int bytes_left = buffer->size - buffer->pos;
int bytes_to_copy = buf_size < bytes_left ? buf_size : bytes_left;
if (bytes_to_copy == 0) {
return AVERROR_EOF;
}
memcpy(buf, buffer->data + buffer->pos, bytes_to_copy);
buffer->pos += bytes_to_copy;
return bytes_to_copy;
}
int main(int argc, char *argv[]) {
av_register_all();
// 读取文件到内存
FILE *file = fopen("test.mp4", "rb");
fseek(file, 0, SEEK_END);
int file_size = ftell(file);
fseek(file, 0, SEEK_SET);
uint8_t *file_data = (uint8_t *)malloc(file_size);
fread(file_data, 1, file_size, file);
fclose(file);
AVIOContext *avio_ctx = NULL;
Buffer buffer = { file_data, file_size, 0 };
avio_ctx = avio_alloc_context(
(uint8_t *)malloc(BUFFER_SIZE),
BUFFER_SIZE,
0,
&buffer,
&read_packet,
NULL,
NULL
);
AVFormatContext *avfmt_ctx = NULL;
int ret = avformat_open_input(&avfmt_ctx, "", NULL, NULL);
if (ret < 0) {
fprintf(stderr, "failed to open input: %s\n", av_err2str(ret));
return 1;
}
avfmt_ctx->pb = avio_ctx;
ret = avformat_find_stream_info(avfmt_ctx, NULL);
if (ret < 0) {
fprintf(stderr, "failed to find stream info: %s\n", av_err2str(ret));
return 1;
}
av_dump_format(avfmt_ctx, 0, "", 0);
avformat_close_input(&avfmt_ctx);
avio_context_free(&avio_ctx);
free(file_data);
return 0;
}
```
这个例子展示了如何通过 `read_packet` 函数从内存中读取数据。你可以将 `Buffer` 结构体中的 `data` 和 `size` 字段换成你自己的数据源,然后在 `read_packet` 函数中读取数据即可。
阅读全文