/*1* Copyright (c) 2014 Stefano Sabatini2*3* Permission is hereby granted, free of charge, to any person obtaining a copy4* of this software and associated documentation files (the "Software"), to deal5* in the Software without restriction, including without limitation the rights6* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell7* copies of the Software, and to permit persons to whom the Software is8* furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER17* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,18* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN19* THE SOFTWARE.20*/2122/**23* @file24* libavformat AVIOContext API example.25*26* Make libavformat demuxer access media content through a custom27* AVIOContext read callback.28* @example avio_reading.c29*/3031#include <libavcodec/avcodec.h>32#include <libavformat/avformat.h>33#include <libavformat/avio.h>34#include <libavutil/file.h>3536struct buffer_data {37uint8_t *ptr;38size_t size; ///< size left in the buffer39};4041static int read_packet(void *opaque, uint8_t *buf, int buf_size)42{43struct buffer_data *bd = (struct buffer_data *)opaque;44buf_size = FFMIN(buf_size, bd->size);4546printf("ptr:%p size:%zu\n", bd->ptr, bd->size);4748/* copy internal buffer data to buf */49memcpy(buf, bd->ptr, buf_size);50bd->ptr += buf_size;51bd->size -= buf_size;5253return buf_size;54}5556int main(int argc, char *argv[])57{58AVFormatContext *fmt_ctx = NULL;59AVIOContext *avio_ctx = NULL;60uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;61size_t buffer_size, avio_ctx_buffer_size = 4096;62char *input_filename = NULL;63int ret = 0;64struct buffer_data bd = { 0 };6566if (argc != 2) {67fprintf(stderr, "usage: %s input_file\n"68"API example program to show how to read from a custom buffer "69"accessed through AVIOContext.\n", argv[0]);70return 1;71}72input_filename = argv[1];7374/* register codecs and formats and other lavf/lavc components*/75av_register_all();7677/* slurp file content into buffer */78ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);79if (ret < 0)80goto end;8182/* fill opaque structure used by the AVIOContext read callback */83bd.ptr = buffer;84bd.size = buffer_size;8586if (!(fmt_ctx = avformat_alloc_context())) {87ret = AVERROR(ENOMEM);88goto end;89}9091avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);92if (!avio_ctx_buffer) {93ret = AVERROR(ENOMEM);94goto end;95}96avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,970, &bd, &read_packet, NULL, NULL);98if (!avio_ctx) {99ret = AVERROR(ENOMEM);100goto end;101}102fmt_ctx->pb = avio_ctx;103104ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);105if (ret < 0) {106fprintf(stderr, "Could not open input\n");107goto end;108}109110ret = avformat_find_stream_info(fmt_ctx, NULL);111if (ret < 0) {112fprintf(stderr, "Could not find stream information\n");113goto end;114}115116av_dump_format(fmt_ctx, 0, input_filename, 0);117118end:119avformat_close_input(&fmt_ctx);120/* note: the internal buffer could have changed, and be != avio_ctx_buffer */121if (avio_ctx) {122av_freep(&avio_ctx->buffer);123av_freep(&avio_ctx);124}125av_file_unmap(buffer, buffer_size);126127if (ret < 0) {128fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));129return 1;130}131132return 0;133}134135136