Skip to content

Instantly share code, notes, and snippets.

@wolfhechel
Created December 4, 2015 08:16
Show Gist options
  • Save wolfhechel/844bd690a0ab52644873 to your computer and use it in GitHub Desktop.
Save wolfhechel/844bd690a0ab52644873 to your computer and use it in GitHub Desktop.
Read AV format through libarchive
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <archive.h>
#include <archive_entry.h>
#include <libavformat/avformat.h>
static int read_archive_packet(void * opaque, uint8_t *buf, int buf_size) {
int data_read = (int)archive_read_data(opaque, buf, (size_t)buf_size);
fprintf(stderr, "buf_size = %d, read %d\n", buf_size, data_read);
if (data_read == 0)
data_read = AVERROR_EOF;
return data_read;
}
void read_av_format(struct archive * archive, struct archive_entry * entry) {
/* Setup buffers */
int ret = 0;
AVFormatContext *fmt_ctx = NULL;
AVIOContext *avio_ctx = NULL;
uint8_t *avio_ctx_buffer = NULL;
size_t avio_ctx_buffer_size = 4096;
if (!(fmt_ctx = avformat_alloc_context())) {
ret = AVERROR(ENOMEM);
goto end;
}
avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
if (!avio_ctx_buffer) {
ret = AVERROR(ENOMEM);
goto end;
}
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
0, archive, &read_archive_packet, NULL, NULL);
if (!avio_ctx) {
ret = AVERROR(ENOMEM);
goto end;
}
fmt_ctx->pb = avio_ctx;
ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Could not open input\n");
goto end;
}
ret = avformat_find_stream_info(fmt_ctx, NULL);
if (ret < 0) {
fprintf(stderr, "Could not find stream information\n");
goto end;
}
av_dump_format(fmt_ctx, 0, archive_entry_pathname(entry), 0);
end:
avformat_close_input(&fmt_ctx);
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
av_freep(&avio_ctx->buffer);
av_freep(&avio_ctx);
if (ret < 0) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
}
}
void read_archive(struct archive * open_archive) {
struct archive_entry *entry;
while (archive_read_next_header(open_archive, &entry) == ARCHIVE_OK) {
printf("file = %s\n", archive_entry_pathname(entry));
read_av_format(open_archive, entry);
}
}
int main(int argc, char *argv[]) {
const char * path = NULL;
struct archive * archive = NULL;
av_register_all();
av_log_set_level(AV_LOG_DEBUG);
for (int a = 1; a < argc; a++) {
path = argv[a];
if (access(path, R_OK) < 0) {
fprintf(stderr, "File %s does not exist\n", path);
break;
}
archive = archive_read_new();
if (archive != NULL) {
if ((archive_read_support_filter_all(archive) != ARCHIVE_OK) ||
(archive_read_support_format_all(archive) != ARCHIVE_OK)) {
archive_read_free(archive);
fprintf(stderr, "Failed to setup libarchive for reading\n");
archive = NULL;
}
}
if (archive != NULL) {
if (archive_read_open_filename(archive, path, 2048) == ARCHIVE_OK) {
read_archive(archive);
}
archive_read_free(archive);
}
}
return 0;
}
CFLAGS += -I$(shell brew --prefix libarchive)/include
CFLAGS += -I$(shell brew --prefix ffmpeg)/include
LDFLAGS += -L$(shell brew --prefix ffmpeg)/lib
LDFLAGS += -L$(shell brew --prefix libarchive)/lib
LDFLAGS += -larchive -lavformat -lavutil
av_archive_decode_OBJS=av_archive_decode.o
av_archive_decode: $(av_archive_decode_OBJS)
$(CC) -o $@ $^ $(LDFLAGS)
all: av_archive_decode
clean:
rm $(av_archive_decode_OBJS)
.PHONY: all clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment