| 69 | } |
| 70 | |
| 71 | int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size) |
| 72 | { |
| 73 | int ret; |
| 74 | int64_t pos, pos_end; |
| 75 | uint8_t *buf, *read_buf[2]; |
| 76 | int read_buf_id = 0; |
| 77 | int read_size[2]; |
| 78 | AVIOContext *read_pb; |
| 79 | |
| 80 | buf = av_malloc_array(shift_size, 2); |
| 81 | if (!buf) |
| 82 | return AVERROR(ENOMEM); |
| 83 | read_buf[0] = buf; |
| 84 | read_buf[1] = buf + shift_size; |
| 85 | |
| 86 | /* Shift the data: the AVIO context of the output can only be used for |
| 87 | * writing, so we re-open the same output, but for reading. It also avoids |
| 88 | * a read/seek/write/seek back and forth. */ |
| 89 | avio_flush(s->pb); |
| 90 | ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL); |
| 91 | if (ret < 0) { |
| 92 | av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for shifting data\n", s->url); |
| 93 | goto end; |
| 94 | } |
| 95 | |
| 96 | /* mark the end of the shift to up to the last data we wrote, and get ready |
| 97 | * for writing */ |
| 98 | pos_end = avio_tell(s->pb); |
| 99 | avio_seek(s->pb, read_start + shift_size, SEEK_SET); |
| 100 | |
| 101 | avio_seek(read_pb, read_start, SEEK_SET); |
| 102 | pos = avio_tell(read_pb); |
| 103 | |
| 104 | #define READ_BLOCK do { \ |
| 105 | read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \ |
| 106 | read_buf_id ^= 1; \ |
| 107 | } while (0) |
| 108 | |
| 109 | /* shift data by chunk of at most shift_size */ |
| 110 | READ_BLOCK; |
| 111 | do { |
| 112 | int n; |
| 113 | READ_BLOCK; |
| 114 | n = read_size[read_buf_id]; |
| 115 | if (n <= 0) |
| 116 | break; |
| 117 | avio_write(s->pb, read_buf[read_buf_id], n); |
| 118 | pos += n; |
| 119 | } while (pos < pos_end); |
| 120 | ret = ff_format_io_close(s, &read_pb); |
| 121 | |
| 122 | end: |
| 123 | av_free(buf); |
| 124 | return ret; |
| 125 | } |
| 126 | |
| 127 | int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options) |
| 128 | { |
no test coverage detected