Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2014 Stefano Sabatini
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  5.  * of this software and associated documentation files (the "Software"), to deal
  6.  * in the Software without restriction, including without limitation the rights
  7.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8.  * copies of the Software, and to permit persons to whom the Software is
  9.  * furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20.  * THE SOFTWARE.
  21.  */
  22.  
  23. /**
  24.  * @file
  25.  * libavformat AVIOContext API example.
  26.  *
  27.  * Make libavformat demuxer access media content through a custom
  28.  * AVIOContext read callback.
  29.  * @example avio_reading.c
  30.  */
  31.  
  32. #include <libavcodec/avcodec.h>
  33. #include <libavformat/avformat.h>
  34. #include <libavformat/avio.h>
  35. #include <libavutil/file.h>
  36.  
  37. struct buffer_data {
  38.     uint8_t *ptr;
  39.     size_t size; ///< size left in the buffer
  40. };
  41.  
  42. static int read_packet(void *opaque, uint8_t *buf, int buf_size)
  43. {
  44.     struct buffer_data *bd = (struct buffer_data *)opaque;
  45.     buf_size = FFMIN(buf_size, bd->size);
  46.  
  47.     printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
  48.  
  49.     /* copy internal buffer data to buf */
  50.     memcpy(buf, bd->ptr, buf_size);
  51.     bd->ptr  += buf_size;
  52.     bd->size -= buf_size;
  53.  
  54.     return buf_size;
  55. }
  56.  
  57. int main(int argc, char *argv[])
  58. {
  59.     AVFormatContext *fmt_ctx = NULL;
  60.     AVIOContext *avio_ctx = NULL;
  61.     uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;
  62.     size_t buffer_size, avio_ctx_buffer_size = 4096;
  63.     char *input_filename = NULL;
  64.     int ret = 0;
  65.     struct buffer_data bd = { 0 };
  66.  
  67.     if (argc != 2) {
  68.         fprintf(stderr, "usage: %s input_file\n"
  69.                 "API example program to show how to read from a custom buffer "
  70.                 "accessed through AVIOContext.\n", argv[0]);
  71.         return 1;
  72.     }
  73.     input_filename = argv[1];
  74.  
  75.     /* register codecs and formats and other lavf/lavc components*/
  76.     av_register_all();
  77.  
  78.     /* slurp file content into buffer */
  79.     ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
  80.     if (ret < 0)
  81.         goto end;
  82.  
  83.     /* fill opaque structure used by the AVIOContext read callback */
  84.     bd.ptr  = buffer;
  85.     bd.size = buffer_size;
  86.  
  87.     if (!(fmt_ctx = avformat_alloc_context())) {
  88.         ret = AVERROR(ENOMEM);
  89.         goto end;
  90.     }
  91.  
  92.     avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
  93.     if (!avio_ctx_buffer) {
  94.         ret = AVERROR(ENOMEM);
  95.         goto end;
  96.     }
  97.     avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
  98.                                   0, &bd, &read_packet, NULL, NULL);
  99.     if (!avio_ctx) {
  100.         ret = AVERROR(ENOMEM);
  101.         goto end;
  102.     }
  103.     fmt_ctx->pb = avio_ctx;
  104.  
  105.     ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);
  106.     if (ret < 0) {
  107.         fprintf(stderr, "Could not open input\n");
  108.         goto end;
  109.     }
  110.  
  111.     ret = avformat_find_stream_info(fmt_ctx, NULL);
  112.     if (ret < 0) {
  113.         fprintf(stderr, "Could not find stream information\n");
  114.         goto end;
  115.     }
  116.  
  117.     av_dump_format(fmt_ctx, 0, input_filename, 0);
  118.  
  119. end:
  120.     avformat_close_input(&fmt_ctx);
  121.     /* note: the internal buffer could have changed, and be != avio_ctx_buffer */
  122.     if (avio_ctx) {
  123.         av_freep(&avio_ctx->buffer);
  124.         av_freep(&avio_ctx);
  125.     }
  126.     av_file_unmap(buffer, buffer_size);
  127.  
  128.     if (ret < 0) {
  129.         fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
  130.         return 1;
  131.     }
  132.  
  133.     return 0;
  134. }
  135.