1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

Merge remote branch 'qatar/master'

* qatar/master: (22 commits)
  ac3enc: move extract_exponents inner loop to ac3dsp
  avio: deprecate url_get_filename().
  avio: deprecate url_max_packet_size().
  avio: make url_get_file_handle() internal.
  avio: make url_filesize() internal.
  avio: make url_close() internal.
  avio: make url_seek() internal.
  avio: cosmetics, move AVSEEK_SIZE/FORCE declarations together
  avio: make url_write() internal.
  avio: make url_read_complete() internal.
  avio: make url_read() internal.
  avio: make url_open() internal.
  avio: make url_connect internal.
  avio: make url_alloc internal.
  applehttp: Merge two for loops
  applehttp: Restructure the demuxer to use a custom AVIOContext
  applehttp: Move finished and target_duration to the variant struct
  aacenc: reduce the number of loop index variables
  avio: deprecate url_open_protocol
  avio: deprecate url_poll and URLPollEntry
  ...

Conflicts:
	libavformat/applehttp.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2011-04-05 02:24:55 +02:00
commit 434f248723
28 changed files with 661 additions and 527 deletions

View File

@ -110,7 +110,7 @@ static av_always_inline float quantize_and_encode_band_cost_template(
const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512]; const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512]; const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
const float CLIPPED_ESCAPE = 165140.0f*IQ; const float CLIPPED_ESCAPE = 165140.0f*IQ;
int i, j, k; int i, j;
float cost = 0; float cost = 0;
const int dim = BT_PAIR ? 2 : 4; const int dim = BT_PAIR ? 2 : 4;
int resbits = 0; int resbits = 0;
@ -149,10 +149,10 @@ static av_always_inline float quantize_and_encode_band_cost_template(
curbits = ff_aac_spectral_bits[cb-1][curidx]; curbits = ff_aac_spectral_bits[cb-1][curidx];
vec = &ff_aac_codebook_vectors[cb-1][curidx*dim]; vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
if (BT_UNSIGNED) { if (BT_UNSIGNED) {
for (k = 0; k < dim; k++) { for (j = 0; j < dim; j++) {
float t = fabsf(in[i+k]); float t = fabsf(in[i+j]);
float di; float di;
if (BT_ESC && vec[k] == 64.0f) { //FIXME: slow if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow
if (t >= CLIPPED_ESCAPE) { if (t >= CLIPPED_ESCAPE) {
di = t - CLIPPED_ESCAPE; di = t - CLIPPED_ESCAPE;
curbits += 21; curbits += 21;
@ -162,15 +162,15 @@ static av_always_inline float quantize_and_encode_band_cost_template(
curbits += av_log2(c)*2 - 4 + 1; curbits += av_log2(c)*2 - 4 + 1;
} }
} else { } else {
di = t - vec[k]*IQ; di = t - vec[j]*IQ;
} }
if (vec[k] != 0.0f) if (vec[j] != 0.0f)
curbits++; curbits++;
rd += di*di; rd += di*di;
} }
} else { } else {
for (k = 0; k < dim; k++) { for (j = 0; j < dim; j++) {
float di = in[i+k] - vec[k]*IQ; float di = in[i+j] - vec[j]*IQ;
rd += di*di; rd += di*di;
} }
} }

View File

@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "libavutil/avassert.h"
#include "avcodec.h" #include "avcodec.h"
#include "ac3.h" #include "ac3.h"
#include "ac3dsp.h" #include "ac3dsp.h"
@ -149,6 +150,27 @@ static int ac3_compute_mantissa_size_c(int mant_cnt[5], uint8_t *bap,
return bits; return bits;
} }
static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs)
{
int i;
for (i = 0; i < nb_coefs; i++) {
int e;
int v = abs(coef[i]);
if (v == 0)
e = 24;
else {
e = 23 - av_log2(v);
if (e >= 24) {
e = 24;
coef[i] = 0;
}
av_assert2(e >= 0);
}
exp[i] = e;
}
}
av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
{ {
c->ac3_exponent_min = ac3_exponent_min_c; c->ac3_exponent_min = ac3_exponent_min_c;
@ -158,6 +180,7 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
c->float_to_fixed24 = float_to_fixed24_c; c->float_to_fixed24 = float_to_fixed24_c;
c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c; c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c;
c->compute_mantissa_size = ac3_compute_mantissa_size_c; c->compute_mantissa_size = ac3_compute_mantissa_size_c;
c->extract_exponents = ac3_extract_exponents_c;
if (ARCH_ARM) if (ARCH_ARM)
ff_ac3dsp_init_arm(c, bit_exact); ff_ac3dsp_init_arm(c, bit_exact);

View File

@ -105,6 +105,8 @@ typedef struct AC3DSPContext {
* Calculate the number of bits needed to encode a set of mantissas. * Calculate the number of bits needed to encode a set of mantissas.
*/ */
int (*compute_mantissa_size)(int mant_cnt[5], uint8_t *bap, int nb_coefs); int (*compute_mantissa_size)(int mant_cnt[5], uint8_t *bap, int nb_coefs);
void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs);
} AC3DSPContext; } AC3DSPContext;
void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact);

View File

@ -329,6 +329,36 @@ static const int64_t ac3_channel_layouts[] = {
}; };
/**
* LUT to select the bandwidth code based on the bit rate, sample rate, and
* number of full-bandwidth channels.
* bandwidth_tab[fbw_channels-1][sample rate code][bit rate code]
*/
static const uint8_t ac3_bandwidth_tab[5][3][19] = {
// 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640
{ { 0, 0, 0, 12, 16, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 },
{ 0, 0, 0, 16, 20, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
{ 0, 0, 0, 32, 40, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } },
{ { 0, 0, 0, 0, 0, 0, 0, 20, 24, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 4, 24, 28, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
{ 0, 0, 0, 0, 0, 0, 20, 44, 52, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 24, 32, 40, 48, 48, 48, 48, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 4, 20, 28, 36, 44, 56, 56, 56, 56, 56, 56 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 20, 40, 48, 60, 60, 60, 60, 60, 60, 60, 60 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 24, 32, 48, 48, 48, 48, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 36, 56, 56, 56, 56, 56, 56 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 48, 60, 60, 60, 60, 60, 60, 60 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 20, 32, 40, 48, 48, 48, 48 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 24, 36, 44, 56, 56, 56, 56 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 44, 60, 60, 60, 60, 60, 60 } }
};
/** /**
* Adjust the frame size to make the average bit rate match the target bit rate. * Adjust the frame size to make the average bit rate match the target bit rate.
* This is only needed for 11025, 22050, and 44100 sample rates. * This is only needed for 11025, 22050, and 44100 sample rates.
@ -532,28 +562,13 @@ static av_cold void exponent_init(AC3EncodeContext *s)
*/ */
static void extract_exponents(AC3EncodeContext *s) static void extract_exponents(AC3EncodeContext *s)
{ {
int blk, ch, i; int blk, ch;
for (ch = 0; ch < s->channels; ch++) { for (ch = 0; ch < s->channels; ch++) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
uint8_t *exp = block->exp[ch]; s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch],
int32_t *coef = block->fixed_coef[ch]; AC3_MAX_COEFS);
for (i = 0; i < AC3_MAX_COEFS; i++) {
int e;
int v = abs(coef[i]);
if (v == 0)
e = 24;
else {
e = 23 - av_log2(v);
if (e >= 24) {
e = 24;
coef[i] = 0;
}
av_assert2(e >= 0);
}
exp[i] = e;
}
} }
} }
} }
@ -2095,9 +2110,7 @@ static av_cold void set_bandwidth(AC3EncodeContext *s)
bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60);
} else { } else {
/* use default bandwidth setting */ /* use default bandwidth setting */
/* XXX: should compute the bandwidth according to the frame bw_code = ac3_bandwidth_tab[s->fbw_channels-1][s->bit_alloc.sr_code][s->frame_size_code/2];
size, so that we avoid annoying high frequency artifacts */
bw_code = 50;
} }
/* set number of coefficients for each channel */ /* set number of coefficients for each channel */

View File

@ -30,6 +30,9 @@
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include <unistd.h> #include <unistd.h>
#include "avio_internal.h"
#define INITIAL_BUFFER_SIZE 32768
/* /*
* An apple http stream consists of a playlist with media segment files, * An apple http stream consists of a playlist with media segment files,
@ -56,26 +59,31 @@ struct segment {
struct variant { struct variant {
int bandwidth; int bandwidth;
char url[MAX_URL_SIZE]; char url[MAX_URL_SIZE];
AVIOContext *pb; AVIOContext pb;
uint8_t* read_buffer;
URLContext *input;
AVFormatContext *parent;
int index;
AVFormatContext *ctx; AVFormatContext *ctx;
AVPacket pkt; AVPacket pkt;
int stream_offset; int stream_offset;
int finished;
int target_duration;
int start_seq_no; int start_seq_no;
int n_segments; int n_segments;
struct segment **segments; struct segment **segments;
int needed; int needed, cur_needed;
int cur_seq_no;
int64_t last_load_time;
}; };
typedef struct AppleHTTPContext { typedef struct AppleHTTPContext {
int target_duration;
int finished;
int n_variants; int n_variants;
struct variant **variants; struct variant **variants;
int cur_seq_no; int cur_seq_no;
int64_t last_load_time; int end_of_segment;
int64_t last_packet_dts; int first_packet;
int max_start_seq, min_end_seq;
} AppleHTTPContext; } AppleHTTPContext;
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@ -102,8 +110,9 @@ static void free_variant_list(AppleHTTPContext *c)
struct variant *var = c->variants[i]; struct variant *var = c->variants[i];
free_segment_list(var); free_segment_list(var);
av_free_packet(&var->pkt); av_free_packet(&var->pkt);
if (var->pb) av_free(var->pb.buffer);
avio_close(var->pb); if (var->input)
url_close(var->input);
if (var->ctx) { if (var->ctx) {
var->ctx->pb = NULL; var->ctx->pb = NULL;
av_close_input_file(var->ctx); av_close_input_file(var->ctx);
@ -170,9 +179,10 @@ static int parse_playlist(AppleHTTPContext *c, const char *url,
goto fail; goto fail;
} }
if (var) if (var) {
free_segment_list(var); free_segment_list(var);
c->finished = 0; var->finished = 0;
}
while (!url_feof(in)) { while (!url_feof(in)) {
read_chomp_line(in, line, sizeof(line)); read_chomp_line(in, line, sizeof(line));
if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) { if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
@ -182,7 +192,14 @@ static int parse_playlist(AppleHTTPContext *c, const char *url,
&info); &info);
bandwidth = atoi(info.bandwidth); bandwidth = atoi(info.bandwidth);
} else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) { } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
c->target_duration = atoi(ptr); if (!var) {
var = new_variant(c, 0, url, NULL);
if (!var) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
var->target_duration = atoi(ptr);
} else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
if (!var) { if (!var) {
var = new_variant(c, 0, url, NULL); var = new_variant(c, 0, url, NULL);
@ -193,7 +210,8 @@ static int parse_playlist(AppleHTTPContext *c, const char *url,
} }
var->start_seq_no = atoi(ptr); var->start_seq_no = atoi(ptr);
} else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
c->finished = 1; if (var)
var->finished = 1;
} else if (av_strstart(line, "#EXTINF:", &ptr)) { } else if (av_strstart(line, "#EXTINF:", &ptr)) {
is_segment = 1; is_segment = 1;
duration = atoi(ptr); duration = atoi(ptr);
@ -229,7 +247,8 @@ static int parse_playlist(AppleHTTPContext *c, const char *url,
} }
} }
} }
c->last_load_time = av_gettime(); if (var)
var->last_load_time = av_gettime();
fail: fail:
if (close_in) if (close_in)
@ -237,6 +256,71 @@ fail:
return ret; return ret;
} }
static int read_data(void *opaque, uint8_t *buf, int buf_size)
{
struct variant *v = opaque;
AppleHTTPContext *c = v->parent->priv_data;
int ret, i;
restart:
if (!v->input) {
reload:
/* If this is a live stream and target_duration has elapsed since
* the last playlist reload, reload the variant playlists now. */
if (!v->finished &&
av_gettime() - v->last_load_time >= v->target_duration*1000000 &&
(ret = parse_playlist(c, v->url, v, NULL)) < 0)
return ret;
if (v->cur_seq_no < v->start_seq_no) {
av_log(NULL, AV_LOG_WARNING,
"skipping %d segments ahead, expired from playlists\n",
v->start_seq_no - v->cur_seq_no);
v->cur_seq_no = v->start_seq_no;
}
if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
if (v->finished)
return AVERROR_EOF;
while (av_gettime() - v->last_load_time <
v->target_duration*1000000) {
if (url_interrupt_cb())
return AVERROR_EXIT;
usleep(100*1000);
}
/* Enough time has elapsed since the last reload */
goto reload;
}
ret = url_open(&v->input,
v->segments[v->cur_seq_no - v->start_seq_no]->url,
URL_RDONLY);
if (ret < 0)
return ret;
}
ret = url_read(v->input, buf, buf_size);
if (ret > 0)
return ret;
if (ret < 0 && ret != AVERROR_EOF)
return ret;
url_close(v->input);
v->input = NULL;
v->cur_seq_no++;
c->end_of_segment = 1;
c->cur_seq_no = v->cur_seq_no;
v->needed = 0;
for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams; i++) {
if (v->parent->streams[i]->discard < AVDISCARD_ALL)
v->needed = 1;
}
if (!v->needed) {
av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
v->index);
return AVERROR_EOF;
}
goto restart;
}
static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap) static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
{ {
AppleHTTPContext *c = s->priv_data; AppleHTTPContext *c = s->priv_data;
@ -268,27 +352,42 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
/* If this isn't a live stream, calculate the total duration of the /* If this isn't a live stream, calculate the total duration of the
* stream. */ * stream. */
if (c->finished) { if (c->variants[0]->finished) {
int64_t duration = 0; int64_t duration = 0;
for (i = 0; i < c->variants[0]->n_segments; i++) for (i = 0; i < c->variants[0]->n_segments; i++)
duration += c->variants[0]->segments[i]->duration; duration += c->variants[0]->segments[i]->duration;
s->duration = duration * AV_TIME_BASE; s->duration = duration * AV_TIME_BASE;
} }
c->min_end_seq = INT_MAX;
/* Open the demuxer for each variant */ /* Open the demuxer for each variant */
for (i = 0; i < c->n_variants; i++) { for (i = 0; i < c->n_variants; i++) {
struct variant *v = c->variants[i]; struct variant *v = c->variants[i];
AVInputFormat *in_fmt = NULL;
if (v->n_segments == 0) if (v->n_segments == 0)
continue; continue;
c->max_start_seq = FFMAX(c->max_start_seq, v->start_seq_no);
c->min_end_seq = FFMIN(c->min_end_seq, v->start_seq_no + v->index = i;
v->n_segments); v->needed = 1;
ret = av_open_input_file(&v->ctx, v->segments[0]->url, NULL, 0, NULL); v->parent = s;
/* If this is a live stream with more than 3 segments, start at the
* third last segment. */
v->cur_seq_no = v->start_seq_no;
if (!v->finished && v->n_segments > 3)
v->cur_seq_no = v->start_seq_no + v->n_segments - 3;
v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
read_data, NULL, NULL);
v->pb.seekable = 0;
ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
NULL, 0, 0);
if (ret < 0)
goto fail;
ret = av_open_input_stream(&v->ctx, &v->pb, v->segments[0]->url,
in_fmt, NULL);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
avio_close(v->ctx->pb);
v->ctx->pb = NULL;
v->stream_offset = stream_offset; v->stream_offset = stream_offset;
/* Create new AVStreams for each stream in this variant */ /* Create new AVStreams for each stream in this variant */
for (j = 0; j < v->ctx->nb_streams; j++) { for (j = 0; j < v->ctx->nb_streams; j++) {
@ -301,13 +400,8 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
} }
stream_offset += v->ctx->nb_streams; stream_offset += v->ctx->nb_streams;
} }
c->last_packet_dts = AV_NOPTS_VALUE;
c->cur_seq_no = c->max_start_seq; c->first_packet = 1;
/* If this is a live stream with more than 3 segments, start at the
* third last segment. */
if (!c->finished && c->min_end_seq - c->max_start_seq > 3)
c->cur_seq_no = c->min_end_seq - 2;
return 0; return 0;
fail: fail:
@ -315,98 +409,61 @@ fail:
return ret; return ret;
} }
static int open_variant(AppleHTTPContext *c, struct variant *var, int skip) static int recheck_discard_flags(AVFormatContext *s, int first)
{ {
int ret; AppleHTTPContext *c = s->priv_data;
int i, changed = 0;
if (c->cur_seq_no < var->start_seq_no) { /* Check if any new streams are needed */
av_log(NULL, AV_LOG_WARNING, for (i = 0; i < c->n_variants; i++)
"seq %d not available in variant %s, skipping\n", c->variants[i]->cur_needed = 0;;
var->start_seq_no, var->url);
return 0; for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
struct variant *var = c->variants[s->streams[i]->id];
if (st->discard < AVDISCARD_ALL)
var->cur_needed = 1;
} }
if (c->cur_seq_no - var->start_seq_no >= var->n_segments) for (i = 0; i < c->n_variants; i++) {
return c->finished ? AVERROR_EOF : 0; struct variant *v = c->variants[i];
ret = avio_open(&var->pb, if (v->cur_needed && !v->needed) {
var->segments[c->cur_seq_no - var->start_seq_no]->url, v->needed = 1;
URL_RDONLY); changed = 1;
if (ret < 0) v->cur_seq_no = c->cur_seq_no;
return ret; v->pb.eof_reached = 0;
var->ctx->pb = var->pb; av_log(s, AV_LOG_INFO, "Now receiving variant %d\n", i);
/* If this is a new segment in parallel with another one already opened, } else if (first && !v->cur_needed && v->needed) {
* skip ahead so they're all at the same dts. */ if (v->input)
if (skip && c->last_packet_dts != AV_NOPTS_VALUE) { url_close(v->input);
while (1) { v->input = NULL;
ret = av_read_frame(var->ctx, &var->pkt); v->needed = 0;
if (ret < 0) { changed = 1;
if (ret == AVERROR_EOF) { av_log(s, AV_LOG_INFO, "No longer receiving variant %d\n", i);
reset_packet(&var->pkt);
return 0;
}
return ret;
}
if (var->pkt.dts >= c->last_packet_dts)
break;
av_free_packet(&var->pkt);
} }
} }
return 0; return changed;
} }
static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt) static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt)
{ {
AppleHTTPContext *c = s->priv_data; AppleHTTPContext *c = s->priv_data;
int ret, i, minvariant = -1, first = 1, needed = 0, changed = 0, int ret, i, minvariant = -1;
variants = 0;
/* Recheck the discard flags - which streams are desired at the moment */ if (c->first_packet) {
for (i = 0; i < c->n_variants; i++) recheck_discard_flags(s, 1);
c->variants[i]->needed = 0; c->first_packet = 0;
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
struct variant *var = c->variants[s->streams[i]->id];
if (st->discard < AVDISCARD_ALL) {
var->needed = 1;
needed++;
} }
/* Copy the discard flag to the chained demuxer, to indicate which
* streams are desired. */
var->ctx->streams[i - var->stream_offset]->discard = st->discard;
}
if (!needed)
return AVERROR_EOF;
start: start:
c->end_of_segment = 0;
for (i = 0; i < c->n_variants; i++) { for (i = 0; i < c->n_variants; i++) {
struct variant *var = c->variants[i]; struct variant *var = c->variants[i];
/* Close unneeded streams, open newly requested streams */
if (var->pb && !var->needed) {
av_log(s, AV_LOG_DEBUG,
"Closing variant stream %d, no longer needed\n", i);
av_free_packet(&var->pkt);
reset_packet(&var->pkt);
avio_close(var->pb);
var->pb = NULL;
changed = 1;
} else if (!var->pb && var->needed) {
if (first)
av_log(s, AV_LOG_DEBUG, "Opening variant stream %d\n", i);
if (first && !c->finished)
if ((ret = parse_playlist(c, var->url, var, NULL)) < 0)
return ret;
ret = open_variant(c, var, first);
if (ret < 0)
return ret;
changed = 1;
}
/* Count the number of open variants */
if (var->pb)
variants++;
/* Make sure we've got one buffered packet from each open variant /* Make sure we've got one buffered packet from each open variant
* stream */ * stream */
if (var->pb && !var->pkt.data) { if (var->needed && !var->pkt.data) {
ret = av_read_frame(var->ctx, &var->pkt); ret = av_read_frame(var->ctx, &var->pkt);
if (ret < 0) { if (ret < 0) {
if (!url_feof(var->pb)) if (!url_feof(&var->pb))
return ret; return ret;
reset_packet(&var->pkt); reset_packet(&var->pkt);
} }
@ -418,70 +475,18 @@ start:
minvariant = i; minvariant = i;
} }
} }
if (first && changed) if (c->end_of_segment) {
av_log(s, AV_LOG_INFO, "Receiving %d variant streams\n", variants); if (recheck_discard_flags(s, 0))
goto start;
}
/* If we got a packet, return it */ /* If we got a packet, return it */
if (minvariant >= 0) { if (minvariant >= 0) {
*pkt = c->variants[minvariant]->pkt; *pkt = c->variants[minvariant]->pkt;
pkt->stream_index += c->variants[minvariant]->stream_offset; pkt->stream_index += c->variants[minvariant]->stream_offset;
reset_packet(&c->variants[minvariant]->pkt); reset_packet(&c->variants[minvariant]->pkt);
c->last_packet_dts = pkt->dts;
return 0; return 0;
} }
/* No more packets - eof reached in all variant streams, close the
* current segments. */
for (i = 0; i < c->n_variants; i++) {
struct variant *var = c->variants[i];
if (var->pb) {
avio_close(var->pb);
var->pb = NULL;
}
}
/* Indicate that we're opening the next segment, not opening a new
* variant stream in parallel, so we shouldn't try to skip ahead. */
first = 0;
c->cur_seq_no++;
reload:
if (!c->finished) {
/* If this is a live stream and target_duration has elapsed since
* the last playlist reload, reload the variant playlists now. */
int64_t now = av_gettime();
if (now - c->last_load_time >= c->target_duration*1000000) {
c->max_start_seq = 0;
c->min_end_seq = INT_MAX;
for (i = 0; i < c->n_variants; i++) {
struct variant *var = c->variants[i];
if (var->needed) {
if ((ret = parse_playlist(c, var->url, var, NULL)) < 0)
return ret;
c->max_start_seq = FFMAX(c->max_start_seq,
var->start_seq_no);
c->min_end_seq = FFMIN(c->min_end_seq,
var->start_seq_no + var->n_segments);
}
}
}
}
if (c->cur_seq_no < c->max_start_seq) {
av_log(NULL, AV_LOG_WARNING,
"skipping %d segments ahead, expired from playlists\n",
c->max_start_seq - c->cur_seq_no);
c->cur_seq_no = c->max_start_seq;
}
/* If more segments exist, open the next one */
if (c->cur_seq_no < c->min_end_seq)
goto start;
/* We've reached the end of the playlists - return eof if this is a
* non-live stream, wait until the next playlist reload if it is live. */
if (c->finished)
return AVERROR_EOF; return AVERROR_EOF;
while (av_gettime() - c->last_load_time < c->target_duration*1000000) {
if (url_interrupt_cb())
return AVERROR_EXIT;
usleep(100*1000);
}
/* Enough time has elapsed since the last reload */
goto reload;
} }
static int applehttp_close(AVFormatContext *s) static int applehttp_close(AVFormatContext *s)
@ -496,38 +501,40 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index,
int64_t timestamp, int flags) int64_t timestamp, int flags)
{ {
AppleHTTPContext *c = s->priv_data; AppleHTTPContext *c = s->priv_data;
int64_t pos = 0; int i, j, ret;
int i;
struct variant *var = c->variants[0];
if ((flags & AVSEEK_FLAG_BYTE) || !c->finished) if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished)
return AVERROR(ENOSYS); return AVERROR(ENOSYS);
/* Reset the variants */
c->last_packet_dts = AV_NOPTS_VALUE;
for (i = 0; i < c->n_variants; i++) {
struct variant *var = c->variants[i];
if (var->pb) {
avio_close(var->pb);
var->pb = NULL;
}
av_free_packet(&var->pkt);
reset_packet(&var->pkt);
}
timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ? timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
s->streams[stream_index]->time_base.den : s->streams[stream_index]->time_base.den :
AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ? AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
AV_ROUND_DOWN : AV_ROUND_UP); AV_ROUND_DOWN : AV_ROUND_UP);
ret = AVERROR(EIO);
for (i = 0; i < c->n_variants; i++) {
/* Reset reading */
struct variant *var = c->variants[i];
int64_t pos = 0;
if (var->input) {
url_close(var->input);
var->input = NULL;
}
av_free_packet(&var->pkt);
reset_packet(&var->pkt);
var->pb.eof_reached = 0;
/* Locate the segment that contains the target timestamp */ /* Locate the segment that contains the target timestamp */
for (i = 0; i < var->n_segments; i++) { for (j = 0; j < var->n_segments; j++) {
if (timestamp >= pos && timestamp < pos + var->segments[i]->duration) { if (timestamp >= pos &&
c->cur_seq_no = var->start_seq_no + i; timestamp < pos + var->segments[j]->duration) {
return 0; var->cur_seq_no = var->start_seq_no + j;
ret = 0;
break;
} }
pos += var->segments[i]->duration; pos += var->segments[j]->duration;
} }
return AVERROR(EIO); }
return ret;
} }
static int applehttp_probe(AVProbeData *p) static int applehttp_probe(AVProbeData *p)

View File

@ -29,6 +29,7 @@
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "url.h"
#include <unistd.h> #include <unistd.h>
/* /*
@ -240,12 +241,12 @@ static int applehttp_read(URLContext *h, uint8_t *buf, int size)
start: start:
if (s->seg_hd) { if (s->seg_hd) {
ret = url_read(s->seg_hd, buf, size); ret = ffurl_read(s->seg_hd, buf, size);
if (ret > 0) if (ret > 0)
return ret; return ret;
} }
if (s->seg_hd) { if (s->seg_hd) {
url_close(s->seg_hd); ffurl_close(s->seg_hd);
s->seg_hd = NULL; s->seg_hd = NULL;
s->cur_seq_no++; s->cur_seq_no++;
} }
@ -274,7 +275,7 @@ retry:
} }
url = s->segments[s->cur_seq_no - s->start_seq_no]->url, url = s->segments[s->cur_seq_no - s->start_seq_no]->url,
av_log(NULL, AV_LOG_DEBUG, "opening %s\n", url); av_log(NULL, AV_LOG_DEBUG, "opening %s\n", url);
ret = url_open(&s->seg_hd, url, URL_RDONLY); ret = ffurl_open(&s->seg_hd, url, URL_RDONLY);
if (ret < 0) { if (ret < 0) {
if (url_interrupt_cb()) if (url_interrupt_cb())
return AVERROR_EXIT; return AVERROR_EXIT;
@ -291,7 +292,7 @@ static int applehttp_close(URLContext *h)
free_segment_list(s); free_segment_list(s);
free_variant_list(s); free_variant_list(s);
url_close(s->seg_hd); ffurl_close(s->seg_hd);
av_free(s); av_free(s);
return 0; return 0;
} }

View File

@ -29,6 +29,7 @@
#if CONFIG_NETWORK #if CONFIG_NETWORK
#include "network.h" #include "network.h"
#endif #endif
#include "url.h"
#if FF_API_URL_CLASS #if FF_API_URL_CLASS
/** @name Logging context. */ /** @name Logging context. */
@ -136,20 +137,21 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
return err; return err;
} }
int url_connect(URLContext* uc) int ffurl_connect(URLContext* uc)
{ {
int err = uc->prot->url_open(uc, uc->filename, uc->flags); int err = uc->prot->url_open(uc, uc->filename, uc->flags);
if (err) if (err)
return err; return err;
uc->is_connected = 1; uc->is_connected = 1;
//We must be careful here as url_seek() could be slow, for example for http //We must be careful here as ffurl_seek() could be slow, for example for http
if( (uc->flags & (URL_WRONLY | URL_RDWR)) if( (uc->flags & (URL_WRONLY | URL_RDWR))
|| !strcmp(uc->prot->name, "file")) || !strcmp(uc->prot->name, "file"))
if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0) if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
uc->is_streamed= 1; uc->is_streamed= 1;
return 0; return 0;
} }
#if FF_API_OLD_AVIO
int url_open_protocol (URLContext **puc, struct URLProtocol *up, int url_open_protocol (URLContext **puc, struct URLProtocol *up,
const char *filename, int flags) const char *filename, int flags)
{ {
@ -158,21 +160,70 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up,
ret = url_alloc_for_protocol(puc, up, filename, flags); ret = url_alloc_for_protocol(puc, up, filename, flags);
if (ret) if (ret)
goto fail; goto fail;
ret = url_connect(*puc); ret = ffurl_connect(*puc);
if (!ret) if (!ret)
return 0; return 0;
fail: fail:
url_close(*puc); ffurl_close(*puc);
*puc = NULL; *puc = NULL;
return ret; return ret;
} }
int url_alloc(URLContext **puc, const char *filename, int flags)
{
return ffurl_alloc(puc, filename, flags);
}
int url_connect(URLContext* uc)
{
return ffurl_connect(uc);
}
int url_open(URLContext **puc, const char *filename, int flags)
{
return ffurl_open(puc, filename, flags);
}
int url_read(URLContext *h, unsigned char *buf, int size)
{
return ffurl_read(h, buf, size);
}
int url_read_complete(URLContext *h, unsigned char *buf, int size)
{
return ffurl_read_complete(h, buf, size);
}
int url_write(URLContext *h, const unsigned char *buf, int size)
{
return ffurl_write(h, buf, size);
}
int64_t url_seek(URLContext *h, int64_t pos, int whence)
{
return ffurl_seek(h, pos, whence);
}
int url_close(URLContext *h)
{
return ffurl_close(h);
}
int64_t url_filesize(URLContext *h)
{
return ffurl_size(h);
}
int url_get_file_handle(URLContext *h)
{
return ffurl_get_file_handle(h);
}
int url_get_max_packet_size(URLContext *h)
{
return h->max_packet_size;
}
void url_get_filename(URLContext *h, char *buf, int buf_size)
{
av_strlcpy(buf, h->filename, buf_size);
}
#endif
#define URL_SCHEME_CHARS \ #define URL_SCHEME_CHARS \
"abcdefghijklmnopqrstuvwxyz" \ "abcdefghijklmnopqrstuvwxyz" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"0123456789+-." "0123456789+-."
int url_alloc(URLContext **puc, const char *filename, int flags) int ffurl_alloc(URLContext **puc, const char *filename, int flags)
{ {
URLProtocol *up; URLProtocol *up;
char proto_str[128], proto_nested[128], *ptr; char proto_str[128], proto_nested[128], *ptr;
@ -200,15 +251,15 @@ int url_alloc(URLContext **puc, const char *filename, int flags)
return AVERROR(ENOENT); return AVERROR(ENOENT);
} }
int url_open(URLContext **puc, const char *filename, int flags) int ffurl_open(URLContext **puc, const char *filename, int flags)
{ {
int ret = url_alloc(puc, filename, flags); int ret = ffurl_alloc(puc, filename, flags);
if (ret) if (ret)
return ret; return ret;
ret = url_connect(*puc); ret = ffurl_connect(*puc);
if (!ret) if (!ret)
return 0; return 0;
url_close(*puc); ffurl_close(*puc);
*puc = NULL; *puc = NULL;
return ret; return ret;
} }
@ -243,21 +294,21 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
return len; return len;
} }
int url_read(URLContext *h, unsigned char *buf, int size) int ffurl_read(URLContext *h, unsigned char *buf, int size)
{ {
if (h->flags & URL_WRONLY) if (h->flags & URL_WRONLY)
return AVERROR(EIO); return AVERROR(EIO);
return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read); return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read);
} }
int url_read_complete(URLContext *h, unsigned char *buf, int size) int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
{ {
if (h->flags & URL_WRONLY) if (h->flags & URL_WRONLY)
return AVERROR(EIO); return AVERROR(EIO);
return retry_transfer_wrapper(h, buf, size, size, h->prot->url_read); return retry_transfer_wrapper(h, buf, size, size, h->prot->url_read);
} }
int url_write(URLContext *h, const unsigned char *buf, int size) int ffurl_write(URLContext *h, const unsigned char *buf, int size)
{ {
if (!(h->flags & (URL_WRONLY | URL_RDWR))) if (!(h->flags & (URL_WRONLY | URL_RDWR)))
return AVERROR(EIO); return AVERROR(EIO);
@ -268,7 +319,7 @@ int url_write(URLContext *h, const unsigned char *buf, int size)
return retry_transfer_wrapper(h, buf, size, size, h->prot->url_write); return retry_transfer_wrapper(h, buf, size, size, h->prot->url_write);
} }
int64_t url_seek(URLContext *h, int64_t pos, int whence) int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
{ {
int64_t ret; int64_t ret;
@ -278,10 +329,10 @@ int64_t url_seek(URLContext *h, int64_t pos, int whence)
return ret; return ret;
} }
int url_close(URLContext *h) int ffurl_close(URLContext *h)
{ {
int ret = 0; int ret = 0;
if (!h) return 0; /* can happen when url_open fails */ if (!h) return 0; /* can happen when ffurl_open fails */
if (h->is_connected && h->prot->url_close) if (h->is_connected && h->prot->url_close)
ret = h->prot->url_close(h); ret = h->prot->url_close(h);
@ -297,45 +348,34 @@ int url_close(URLContext *h)
int url_exist(const char *filename) int url_exist(const char *filename)
{ {
URLContext *h; URLContext *h;
if (url_open(&h, filename, URL_RDONLY) < 0) if (ffurl_open(&h, filename, URL_RDONLY) < 0)
return 0; return 0;
url_close(h); ffurl_close(h);
return 1; return 1;
} }
int64_t url_filesize(URLContext *h) int64_t ffurl_size(URLContext *h)
{ {
int64_t pos, size; int64_t pos, size;
size= url_seek(h, 0, AVSEEK_SIZE); size= ffurl_seek(h, 0, AVSEEK_SIZE);
if(size<0){ if(size<0){
pos = url_seek(h, 0, SEEK_CUR); pos = ffurl_seek(h, 0, SEEK_CUR);
if ((size = url_seek(h, -1, SEEK_END)) < 0) if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
return size; return size;
size++; size++;
url_seek(h, pos, SEEK_SET); ffurl_seek(h, pos, SEEK_SET);
} }
return size; return size;
} }
int url_get_file_handle(URLContext *h) int ffurl_get_file_handle(URLContext *h)
{ {
if (!h->prot->url_get_file_handle) if (!h->prot->url_get_file_handle)
return -1; return -1;
return h->prot->url_get_file_handle(h); return h->prot->url_get_file_handle(h);
} }
int url_get_max_packet_size(URLContext *h)
{
return h->max_packet_size;
}
void url_get_filename(URLContext *h, char *buf, int buf_size)
{
av_strlcpy(buf, h->filename, buf_size);
}
static int default_interrupt_cb(void) static int default_interrupt_cb(void)
{ {
return 0; return 0;

View File

@ -57,11 +57,13 @@ typedef struct URLContext {
int is_connected; int is_connected;
} URLContext; } URLContext;
#if FF_API_OLD_AVIO
typedef struct URLPollEntry { typedef struct URLPollEntry {
URLContext *handle; URLContext *handle;
int events; int events;
int revents; int revents;
} URLPollEntry; } URLPollEntry;
#endif
/** /**
* @defgroup open_modes URL open modes * @defgroup open_modes URL open modes
@ -92,110 +94,27 @@ typedef struct URLPollEntry {
typedef int URLInterruptCB(void); typedef int URLInterruptCB(void);
#if FF_API_OLD_AVIO
/** /**
* Create a URLContext for accessing to the resource indicated by * @defgroup old_url_funcs Old url_* functions
* url, and open it using the URLProtocol up. * @deprecated use the buffered API based on AVIOContext instead
* * @{
* @param puc pointer to the location where, in case of success, the
* function puts the pointer to the created URLContext
* @param flags flags which control how the resource indicated by url
* is to be opened
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/ */
int url_open_protocol (URLContext **puc, struct URLProtocol *up, attribute_deprecated int url_open_protocol (URLContext **puc, struct URLProtocol *up,
const char *url, int flags); const char *url, int flags);
attribute_deprecated int url_alloc(URLContext **h, const char *url, int flags);
/** attribute_deprecated int url_connect(URLContext *h);
* Create a URLContext for accessing to the resource indicated by attribute_deprecated int url_open(URLContext **h, const char *url, int flags);
* url, but do not initiate the connection yet. attribute_deprecated int url_read(URLContext *h, unsigned char *buf, int size);
* attribute_deprecated int url_read_complete(URLContext *h, unsigned char *buf, int size);
* @param puc pointer to the location where, in case of success, the attribute_deprecated int url_write(URLContext *h, const unsigned char *buf, int size);
* function puts the pointer to the created URLContext attribute_deprecated int64_t url_seek(URLContext *h, int64_t pos, int whence);
* @param flags flags which control how the resource indicated by url attribute_deprecated int url_close(URLContext *h);
* is to be opened attribute_deprecated int64_t url_filesize(URLContext *h);
* @return 0 in case of success, a negative value corresponding to an attribute_deprecated int url_get_file_handle(URLContext *h);
* AVERROR code in case of failure attribute_deprecated int url_get_max_packet_size(URLContext *h);
*/ attribute_deprecated void url_get_filename(URLContext *h, char *buf, int buf_size);
int url_alloc(URLContext **h, const char *url, int flags); #endif
/**
* Connect an URLContext that has been allocated by url_alloc
*/
int url_connect(URLContext *h);
/**
* Create an URLContext for accessing to the resource indicated by
* url, and open it.
*
* @param puc pointer to the location where, in case of success, the
* function puts the pointer to the created URLContext
* @param flags flags which control how the resource indicated by url
* is to be opened
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int url_open(URLContext **h, const char *url, int flags);
/**
* Read up to size bytes from the resource accessed by h, and store
* the read bytes in buf.
*
* @return The number of bytes actually read, or a negative value
* corresponding to an AVERROR code in case of error. A value of zero
* indicates that it is not possible to read more from the accessed
* resource (except if the value of the size argument is also zero).
*/
int url_read(URLContext *h, unsigned char *buf, int size);
/**
* Read as many bytes as possible (up to size), calling the
* read function multiple times if necessary.
* This makes special short-read handling in applications
* unnecessary, if the return value is < size then it is
* certain there was either an error or the end of file was reached.
*/
int url_read_complete(URLContext *h, unsigned char *buf, int size);
/**
* Write size bytes from buf to the resource accessed by h.
*
* @return the number of bytes actually written, or a negative value
* corresponding to an AVERROR code in case of failure
*/
int url_write(URLContext *h, const unsigned char *buf, int size);
/**
* Passing this as the "whence" parameter to a seek function causes it to
* return the filesize without seeking anywhere. Supporting this is optional.
* If it is not supported then the seek function will return <0.
*/
#define AVSEEK_SIZE 0x10000
/**
* Change the position that will be used by the next read/write
* operation on the resource accessed by h.
*
* @param pos specifies the new position to set
* @param whence specifies how pos should be interpreted, it must be
* one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the
* current position), SEEK_END (seek from the end), or AVSEEK_SIZE
* (return the filesize of the requested resource, pos is ignored).
* @return a negative value corresponding to an AVERROR code in case
* of failure, or the resulting file position, measured in bytes from
* the beginning of the file. You can use this feature together with
* SEEK_CUR to read the current file position.
*/
int64_t url_seek(URLContext *h, int64_t pos, int whence);
/**
* Close the resource accessed by the URLContext h, and free the
* memory used by it.
*
* @return a negative value if an error condition occurred, 0
* otherwise
*/
int url_close(URLContext *h);
/** /**
* Return a non-zero value if the resource indicated by url * Return a non-zero value if the resource indicated by url
@ -203,38 +122,6 @@ int url_close(URLContext *h);
*/ */
int url_exist(const char *url); int url_exist(const char *url);
/**
* Return the filesize of the resource accessed by h, AVERROR(ENOSYS)
* if the operation is not supported by h, or another negative value
* corresponding to an AVERROR error code in case of failure.
*/
int64_t url_filesize(URLContext *h);
/**
* Return the file descriptor associated with this URL. For RTP, this
* will return only the RTP file descriptor, not the RTCP file descriptor.
*
* @return the file descriptor associated with this URL, or <0 on error.
*/
int url_get_file_handle(URLContext *h);
/**
* Return the maximum packet size associated to packetized file
* handle. If the file is not packetized (stream like HTTP or file on
* disk), then 0 is returned.
*
* @param h file handle
* @return maximum packet size in bytes
*/
int url_get_max_packet_size(URLContext *h);
/**
* Copy the filename of the resource accessed by h to buf.
*
* @param buf_size size in bytes of buf
*/
void url_get_filename(URLContext *h, char *buf, int buf_size);
/** /**
* The callback is called in blocking functions to test regulary if * The callback is called in blocking functions to test regulary if
* asynchronous interruption is needed. AVERROR_EXIT is returned * asynchronous interruption is needed. AVERROR_EXIT is returned
@ -243,8 +130,10 @@ void url_get_filename(URLContext *h, char *buf, int buf_size);
*/ */
void url_set_interrupt_cb(URLInterruptCB *interrupt_cb); void url_set_interrupt_cb(URLInterruptCB *interrupt_cb);
#if FF_API_OLD_AVIO
/* not implemented */ /* not implemented */
int url_poll(URLPollEntry *poll_table, int n, int timeout); attribute_deprecated int url_poll(URLPollEntry *poll_table, int n, int timeout);
#endif
/** /**
* Pause and resume playing - only meaningful if using a network streaming * Pause and resume playing - only meaningful if using a network streaming
@ -273,14 +162,6 @@ int av_url_read_pause(URLContext *h, int pause);
int64_t av_url_read_seek(URLContext *h, int stream_index, int64_t av_url_read_seek(URLContext *h, int stream_index,
int64_t timestamp, int flags); int64_t timestamp, int flags);
/**
* Oring this flag as into the "whence" parameter to a seek function causes it to
* seek by any means (like reopening and linear reading) or other normally unreasonble
* means that can be extreemly slow.
* This may be ignored by the seek code.
*/
#define AVSEEK_FORCE 0x20000
#define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */ #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */
typedef struct URLProtocol { typedef struct URLProtocol {
@ -334,6 +215,10 @@ int av_register_protocol2(URLProtocol *protocol, int size);
#define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */ #define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */
/**
* @}
*/
/** /**
* Bytestream IO Context. * Bytestream IO Context.
* New fields can be added to the end with minor version bumps. * New fields can be added to the end with minor version bumps.
@ -518,6 +403,21 @@ int avio_put_str(AVIOContext *s, const char *str);
*/ */
int avio_put_str16le(AVIOContext *s, const char *str); int avio_put_str16le(AVIOContext *s, const char *str);
/**
* Passing this as the "whence" parameter to a seek function causes it to
* return the filesize without seeking anywhere. Supporting this is optional.
* If it is not supported then the seek function will return <0.
*/
#define AVSEEK_SIZE 0x10000
/**
* Oring this flag as into the "whence" parameter to a seek function causes it to
* seek by any means (like reopening and linear reading) or other normally unreasonble
* means that can be extreemly slow.
* This may be ignored by the seek code.
*/
#define AVSEEK_FORCE 0x20000
/** /**
* fseek() equivalent for AVIOContext. * fseek() equivalent for AVIOContext.
* @return new position or AVERROR. * @return new position or AVERROR.

View File

@ -25,6 +25,7 @@
#include "avio.h" #include "avio.h"
#include "avio_internal.h" #include "avio_internal.h"
#include "internal.h" #include "internal.h"
#include "url.h"
#include <stdarg.h> #include <stdarg.h>
#define IO_BUFFER_SIZE 32768 #define IO_BUFFER_SIZE 32768
@ -836,7 +837,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
uint8_t *buffer; uint8_t *buffer;
int buffer_size, max_packet_size; int buffer_size, max_packet_size;
max_packet_size = url_get_max_packet_size(h); max_packet_size = h->max_packet_size;
if (max_packet_size) { if (max_packet_size) {
buffer_size = max_packet_size; /* no need to bufferize more than one packet */ buffer_size = max_packet_size; /* no need to bufferize more than one packet */
} else { } else {
@ -854,7 +855,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
if (ffio_init_context(*s, buffer, buffer_size, if (ffio_init_context(*s, buffer, buffer_size,
(h->flags & URL_WRONLY || h->flags & URL_RDWR), h, (h->flags & URL_WRONLY || h->flags & URL_RDWR), h,
url_read, url_write, url_seek) < 0) { ffurl_read, ffurl_write, ffurl_seek) < 0) {
av_free(buffer); av_free(buffer);
av_freep(s); av_freep(s);
return AVERROR(EIO); return AVERROR(EIO);
@ -953,12 +954,12 @@ int avio_open(AVIOContext **s, const char *filename, int flags)
URLContext *h; URLContext *h;
int err; int err;
err = url_open(&h, filename, flags); err = ffurl_open(&h, filename, flags);
if (err < 0) if (err < 0)
return err; return err;
err = ffio_fdopen(s, h); err = ffio_fdopen(s, h);
if (err < 0) { if (err < 0) {
url_close(h); ffurl_close(h);
return err; return err;
} }
return 0; return 0;
@ -970,7 +971,7 @@ int avio_close(AVIOContext *s)
av_free(s->buffer); av_free(s->buffer);
av_free(s); av_free(s);
return url_close(h); return ffurl_close(h);
} }
#if FF_API_OLD_AVIO #if FF_API_OLD_AVIO

View File

@ -24,6 +24,7 @@
#include "avformat.h" #include "avformat.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/mem.h" #include "libavutil/mem.h"
#include "url.h"
#define AV_CAT_SEPARATOR "|" #define AV_CAT_SEPARATOR "|"
@ -46,7 +47,7 @@ static av_cold int concat_close(URLContext *h)
struct concat_nodes *nodes = data->nodes; struct concat_nodes *nodes = data->nodes;
for (i = 0; i != data->length; i++) for (i = 0; i != data->length; i++)
err |= url_close(nodes[i].uc); err |= ffurl_close(nodes[i].uc);
av_freep(&data->nodes); av_freep(&data->nodes);
av_freep(&h->priv_data); av_freep(&h->priv_data);
@ -100,12 +101,12 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
uri += len + strspn(uri+len, AV_CAT_SEPARATOR); uri += len + strspn(uri+len, AV_CAT_SEPARATOR);
/* creating URLContext */ /* creating URLContext */
if ((err = url_open(&uc, node_uri, flags)) < 0) if ((err = ffurl_open(&uc, node_uri, flags)) < 0)
break; break;
/* creating size */ /* creating size */
if ((size = url_filesize(uc)) < 0) { if ((size = ffurl_size(uc)) < 0) {
url_close(uc); ffurl_close(uc);
err = AVERROR(ENOSYS); err = AVERROR(ENOSYS);
break; break;
} }
@ -135,12 +136,12 @@ static int concat_read(URLContext *h, unsigned char *buf, int size)
size_t i = data->current; size_t i = data->current;
while (size > 0) { while (size > 0) {
result = url_read(nodes[i].uc, buf, size); result = ffurl_read(nodes[i].uc, buf, size);
if (result < 0) if (result < 0)
return total ? total : result; return total ? total : result;
if (!result) if (!result)
if (i + 1 == data->length || if (i + 1 == data->length ||
url_seek(nodes[++i].uc, 0, SEEK_SET) < 0) ffurl_seek(nodes[++i].uc, 0, SEEK_SET) < 0)
break; break;
total += result; total += result;
buf += result; buf += result;
@ -168,7 +169,7 @@ static int64_t concat_seek(URLContext *h, int64_t pos, int whence)
/* get the absolute position */ /* get the absolute position */
for (i = 0; i != data->current; i++) for (i = 0; i != data->current; i++)
pos += nodes[i].size; pos += nodes[i].size;
pos += url_seek(nodes[i].uc, 0, SEEK_CUR); pos += ffurl_seek(nodes[i].uc, 0, SEEK_CUR);
whence = SEEK_SET; whence = SEEK_SET;
/* fall through with the absolute position */ /* fall through with the absolute position */
case SEEK_SET: case SEEK_SET:
@ -179,7 +180,7 @@ static int64_t concat_seek(URLContext *h, int64_t pos, int whence)
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
result = url_seek(nodes[i].uc, pos, whence); result = ffurl_seek(nodes[i].uc, pos, whence);
if (result >= 0) { if (result >= 0) {
data->current = i; data->current = i;
while (i) while (i)

View File

@ -26,6 +26,7 @@
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "network.h" #include "network.h"
#include "url.h"
typedef struct { typedef struct {
URLContext *hd; URLContext *hd;
@ -34,7 +35,7 @@ typedef struct {
static int gopher_write(URLContext *h, const uint8_t *buf, int size) static int gopher_write(URLContext *h, const uint8_t *buf, int size)
{ {
GopherContext *s = h->priv_data; GopherContext *s = h->priv_data;
return url_write(s->hd, buf, size); return ffurl_write(s->hd, buf, size);
} }
static int gopher_connect(URLContext *h, const char *path) static int gopher_connect(URLContext *h, const char *path)
@ -68,7 +69,7 @@ static int gopher_close(URLContext *h)
{ {
GopherContext *s = h->priv_data; GopherContext *s = h->priv_data;
if (s->hd) { if (s->hd) {
url_close(s->hd); ffurl_close(s->hd);
s->hd = NULL; s->hd = NULL;
} }
av_freep(&h->priv_data); av_freep(&h->priv_data);
@ -99,7 +100,7 @@ static int gopher_open(URLContext *h, const char *uri, int flags)
ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
s->hd = NULL; s->hd = NULL;
err = url_open(&s->hd, buf, URL_RDWR); err = ffurl_open(&s->hd, buf, URL_RDWR);
if (err < 0) if (err < 0)
goto fail; goto fail;
@ -114,7 +115,7 @@ static int gopher_open(URLContext *h, const char *uri, int flags)
static int gopher_read(URLContext *h, uint8_t *buf, int size) static int gopher_read(URLContext *h, uint8_t *buf, int size)
{ {
GopherContext *s = h->priv_data; GopherContext *s = h->priv_data;
int len = url_read(s->hd, buf, size); int len = ffurl_read(s->hd, buf, size);
return len; return len;
} }

View File

@ -28,6 +28,7 @@
#include "http.h" #include "http.h"
#include "os_support.h" #include "os_support.h"
#include "httpauth.h" #include "httpauth.h"
#include "url.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
/* XXX: POST protocol is not completely implemented because ffmpeg uses /* XXX: POST protocol is not completely implemented because ffmpeg uses
@ -123,7 +124,7 @@ static int http_open_cnx(URLContext *h)
port = 80; port = 80;
ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
err = url_open(&hd, buf, URL_RDWR); err = ffurl_open(&hd, buf, URL_RDWR);
if (err < 0) if (err < 0)
goto fail; goto fail;
@ -133,7 +134,7 @@ static int http_open_cnx(URLContext *h)
goto fail; goto fail;
if (s->http_code == 401) { if (s->http_code == 401) {
if (cur_auth_type == HTTP_AUTH_NONE && s->auth_state.auth_type != HTTP_AUTH_NONE) { if (cur_auth_type == HTTP_AUTH_NONE && s->auth_state.auth_type != HTTP_AUTH_NONE) {
url_close(hd); ffurl_close(hd);
goto redo; goto redo;
} else } else
goto fail; goto fail;
@ -141,7 +142,7 @@ static int http_open_cnx(URLContext *h)
if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307) if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307)
&& location_changed == 1) { && location_changed == 1) {
/* url moved, get next */ /* url moved, get next */
url_close(hd); ffurl_close(hd);
if (redirects++ >= MAX_REDIRECTS) if (redirects++ >= MAX_REDIRECTS)
return AVERROR(EIO); return AVERROR(EIO);
location_changed = 0; location_changed = 0;
@ -150,7 +151,7 @@ static int http_open_cnx(URLContext *h)
return 0; return 0;
fail: fail:
if (hd) if (hd)
url_close(hd); ffurl_close(hd);
s->hd = NULL; s->hd = NULL;
return AVERROR(EIO); return AVERROR(EIO);
} }
@ -170,7 +171,7 @@ static int http_getc(HTTPContext *s)
{ {
int len; int len;
if (s->buf_ptr >= s->buf_end) { if (s->buf_ptr >= s->buf_end) {
len = url_read(s->hd, s->buffer, BUFFER_SIZE); len = ffurl_read(s->hd, s->buffer, BUFFER_SIZE);
if (len < 0) { if (len < 0) {
return AVERROR(EIO); return AVERROR(EIO);
} else if (len == 0) { } else if (len == 0) {
@ -332,7 +333,7 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
authstr ? authstr : ""); authstr ? authstr : "");
av_freep(&authstr); av_freep(&authstr);
if (url_write(s->hd, s->buffer, strlen(s->buffer)) < 0) if (ffurl_write(s->hd, s->buffer, strlen(s->buffer)) < 0)
return AVERROR(EIO); return AVERROR(EIO);
/* init input buffer */ /* init input buffer */
@ -406,7 +407,7 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
} else { } else {
if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize) if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize)
return AVERROR_EOF; return AVERROR_EOF;
len = url_read(s->hd, buf, size); len = ffurl_read(s->hd, buf, size);
} }
if (len > 0) { if (len > 0) {
s->off += len; s->off += len;
@ -426,7 +427,7 @@ static int http_write(URLContext *h, const uint8_t *buf, int size)
if (s->chunksize == -1) { if (s->chunksize == -1) {
/* non-chunked data is sent without any special encoding */ /* non-chunked data is sent without any special encoding */
return url_write(s->hd, buf, size); return ffurl_write(s->hd, buf, size);
} }
/* silently ignore zero-size data since chunk encoding that would /* silently ignore zero-size data since chunk encoding that would
@ -435,9 +436,9 @@ static int http_write(URLContext *h, const uint8_t *buf, int size)
/* upload data using chunked encoding */ /* upload data using chunked encoding */
snprintf(temp, sizeof(temp), "%x\r\n", size); snprintf(temp, sizeof(temp), "%x\r\n", size);
if ((ret = url_write(s->hd, temp, strlen(temp))) < 0 || if ((ret = ffurl_write(s->hd, temp, strlen(temp))) < 0 ||
(ret = url_write(s->hd, buf, size)) < 0 || (ret = ffurl_write(s->hd, buf, size)) < 0 ||
(ret = url_write(s->hd, crlf, sizeof(crlf) - 1)) < 0) (ret = ffurl_write(s->hd, crlf, sizeof(crlf) - 1)) < 0)
return ret; return ret;
} }
return size; return size;
@ -451,12 +452,12 @@ static int http_close(URLContext *h)
/* signal end of chunked encoding if used */ /* signal end of chunked encoding if used */
if ((h->flags & URL_WRONLY) && s->chunksize != -1) { if ((h->flags & URL_WRONLY) && s->chunksize != -1) {
ret = url_write(s->hd, footer, sizeof(footer) - 1); ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
ret = ret > 0 ? 0 : ret; ret = ret > 0 ? 0 : ret;
} }
if (s->hd) if (s->hd)
url_close(s->hd); ffurl_close(s->hd);
return ret; return ret;
} }
@ -492,7 +493,7 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
s->off = old_off; s->off = old_off;
return -1; return -1;
} }
url_close(old_hd); ffurl_close(old_hd);
return off; return off;
} }
@ -500,7 +501,7 @@ static int
http_get_file_handle(URLContext *h) http_get_file_handle(URLContext *h)
{ {
HTTPContext *s = h->priv_data; HTTPContext *s = h->priv_data;
return url_get_file_handle(s->hd); return ffurl_get_file_handle(s->hd);
} }
URLProtocol ff_http_protocol = { URLProtocol ff_http_protocol = {

View File

@ -25,6 +25,7 @@
#include "libavutil/error.h" #include "libavutil/error.h"
#include "avformat.h" #include "avformat.h"
#include "avio.h" #include "avio.h"
#include "url.h"
#define PRIV_SIZE 128 #define PRIV_SIZE 128
@ -64,11 +65,11 @@ static int md5_close(URLContext *h)
av_strstart(filename, "md5:", &filename); av_strstart(filename, "md5:", &filename);
if (*filename) { if (*filename) {
err = url_open(&out, filename, URL_WRONLY); err = ffurl_open(&out, filename, URL_WRONLY);
if (err) if (err)
return err; return err;
err = url_write(out, buf, i*2+1); err = ffurl_write(out, buf, i*2+1);
url_close(out); ffurl_close(out);
} else { } else {
if (fwrite(buf, 1, i*2+1, stdout) < i*2+1) if (fwrite(buf, 1, i*2+1, stdout) < i*2+1)
err = AVERROR(errno); err = AVERROR(errno);

View File

@ -32,6 +32,7 @@
#include "mms.h" #include "mms.h"
#include "asf.h" #include "asf.h"
#include "http.h" #include "http.h"
#include "url.h"
#define CHUNK_HEADER_LENGTH 4 // 2bytes chunk type and 2bytes chunk length. #define CHUNK_HEADER_LENGTH 4 // 2bytes chunk type and 2bytes chunk length.
#define EXT_HEADER_LENGTH 8 // 4bytes sequence, 2bytes useless and 2bytes chunk length. #define EXT_HEADER_LENGTH 8 // 4bytes sequence, 2bytes useless and 2bytes chunk length.
@ -63,7 +64,7 @@ static int mmsh_close(URLContext *h)
MMSHContext *mmsh = (MMSHContext *)h->priv_data; MMSHContext *mmsh = (MMSHContext *)h->priv_data;
MMSContext *mms = &mmsh->mms; MMSContext *mms = &mmsh->mms;
if (mms->mms_hd) if (mms->mms_hd)
url_close(mms->mms_hd); ffurl_close(mms->mms_hd);
av_free(mms->streams); av_free(mms->streams);
av_free(mms->asf_header); av_free(mms->asf_header);
av_freep(&h->priv_data); av_freep(&h->priv_data);
@ -78,7 +79,7 @@ static ChunkType get_chunk_header(MMSHContext *mmsh, int *len)
ChunkType chunk_type; ChunkType chunk_type;
int chunk_len, res, ext_header_len; int chunk_len, res, ext_header_len;
res = url_read_complete(mms->mms_hd, chunk_header, CHUNK_HEADER_LENGTH); res = ffurl_read_complete(mms->mms_hd, chunk_header, CHUNK_HEADER_LENGTH);
if (res != CHUNK_HEADER_LENGTH) { if (res != CHUNK_HEADER_LENGTH) {
av_log(NULL, AV_LOG_ERROR, "Read data packet header failed!\n"); av_log(NULL, AV_LOG_ERROR, "Read data packet header failed!\n");
return AVERROR(EIO); return AVERROR(EIO);
@ -100,7 +101,7 @@ static ChunkType get_chunk_header(MMSHContext *mmsh, int *len)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
res = url_read_complete(mms->mms_hd, ext_header, ext_header_len); res = ffurl_read_complete(mms->mms_hd, ext_header, ext_header_len);
if (res != ext_header_len) { if (res != ext_header_len) {
av_log(NULL, AV_LOG_ERROR, "Read ext header failed!\n"); av_log(NULL, AV_LOG_ERROR, "Read ext header failed!\n");
return AVERROR(EIO); return AVERROR(EIO);
@ -121,7 +122,7 @@ static int read_data_packet(MMSHContext *mmsh, const int len)
len, sizeof(mms->in_buffer)); len, sizeof(mms->in_buffer));
return AVERROR(EIO); return AVERROR(EIO);
} }
res = url_read_complete(mms->mms_hd, mms->in_buffer, len); res = ffurl_read_complete(mms->mms_hd, mms->in_buffer, len);
av_dlog(NULL, "Data packet len = %d\n", len); av_dlog(NULL, "Data packet len = %d\n", len);
if (res != len) { if (res != len) {
av_log(NULL, AV_LOG_ERROR, "Read data packet failed!\n"); av_log(NULL, AV_LOG_ERROR, "Read data packet failed!\n");
@ -173,7 +174,7 @@ static int get_http_header_data(MMSHContext *mmsh)
len, mms->asf_header_size); len, mms->asf_header_size);
return AVERROR(EIO); return AVERROR(EIO);
} }
res = url_read_complete(mms->mms_hd, mms->asf_header, len); res = ffurl_read_complete(mms->mms_hd, mms->asf_header, len);
if (res != len) { if (res != len) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
"Recv asf header data len %d != expected len %d\n", res, len); "Recv asf header data len %d != expected len %d\n", res, len);
@ -196,7 +197,7 @@ static int get_http_header_data(MMSHContext *mmsh)
len, sizeof(mms->in_buffer)); len, sizeof(mms->in_buffer));
return AVERROR(EIO); return AVERROR(EIO);
} }
res = url_read_complete(mms->mms_hd, mms->in_buffer, len); res = ffurl_read_complete(mms->mms_hd, mms->in_buffer, len);
if (res != len) { if (res != len) {
av_log(NULL, AV_LOG_ERROR, "Read other chunk type data failed!\n"); av_log(NULL, AV_LOG_ERROR, "Read other chunk type data failed!\n");
return AVERROR(EIO); return AVERROR(EIO);
@ -232,7 +233,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
port = 80; // default mmsh protocol port port = 80; // default mmsh protocol port
ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, path); ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, path);
if (url_alloc(&mms->mms_hd, httpname, URL_RDONLY) < 0) { if (ffurl_alloc(&mms->mms_hd, httpname, URL_RDONLY) < 0) {
return AVERROR(EIO); return AVERROR(EIO);
} }
@ -247,7 +248,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
host, port, mmsh->request_seq++); host, port, mmsh->request_seq++);
ff_http_set_headers(mms->mms_hd, headers); ff_http_set_headers(mms->mms_hd, headers);
err = url_connect(mms->mms_hd); err = ffurl_connect(mms->mms_hd);
if (err) { if (err) {
goto fail; goto fail;
} }
@ -258,9 +259,9 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
} }
// close the socket and then reopen it for sending the second play request. // close the socket and then reopen it for sending the second play request.
url_close(mms->mms_hd); ffurl_close(mms->mms_hd);
memset(headers, 0, sizeof(headers)); memset(headers, 0, sizeof(headers));
if (url_alloc(&mms->mms_hd, httpname, URL_RDONLY) < 0) { if (ffurl_alloc(&mms->mms_hd, httpname, URL_RDONLY) < 0) {
return AVERROR(EIO); return AVERROR(EIO);
} }
stream_selection = av_mallocz(mms->stream_num * 19 + 1); stream_selection = av_mallocz(mms->stream_num * 19 + 1);
@ -293,7 +294,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
av_dlog(NULL, "out_buffer is %s", headers); av_dlog(NULL, "out_buffer is %s", headers);
ff_http_set_headers(mms->mms_hd, headers); ff_http_set_headers(mms->mms_hd, headers);
err = url_connect(mms->mms_hd); err = ffurl_connect(mms->mms_hd);
if (err) { if (err) {
goto fail; goto fail;
} }

View File

@ -35,6 +35,7 @@
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavcodec/bytestream.h" #include "libavcodec/bytestream.h"
#include "network.h" #include "network.h"
#include "url.h"
#define LOCAL_ADDRESS 0xc0a80081 // FIXME get and use correct local ip address. #define LOCAL_ADDRESS 0xc0a80081 // FIXME get and use correct local ip address.
#define LOCAL_PORT 1037 // as above. #define LOCAL_PORT 1037 // as above.
@ -138,7 +139,7 @@ static int send_command_packet(MMSTContext *mmst)
memset(mms->write_out_ptr, 0, exact_length - len); memset(mms->write_out_ptr, 0, exact_length - len);
// write it out. // write it out.
write_result= url_write(mms->mms_hd, mms->out_buffer, exact_length); write_result= ffurl_write(mms->mms_hd, mms->out_buffer, exact_length);
if(write_result != exact_length) { if(write_result != exact_length) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
"Failed to write data of length %d: %d (%s)\n", "Failed to write data of length %d: %d (%s)\n",
@ -240,7 +241,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
MMSSCPacketType packet_type= -1; MMSSCPacketType packet_type= -1;
MMSContext *mms = &mmst->mms; MMSContext *mms = &mmst->mms;
for(;;) { for(;;) {
read_result = url_read_complete(mms->mms_hd, mms->in_buffer, 8); read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer, 8);
if (read_result != 8) { if (read_result != 8) {
if(read_result < 0) { if(read_result < 0) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
@ -260,7 +261,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
int length_remaining, hr; int length_remaining, hr;
mmst->incoming_flags= mms->in_buffer[3]; mmst->incoming_flags= mms->in_buffer[3];
read_result= url_read_complete(mms->mms_hd, mms->in_buffer+8, 4); read_result= ffurl_read_complete(mms->mms_hd, mms->in_buffer+8, 4);
if(read_result != 4) { if(read_result != 4) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
"Reading command packet length failed: %d (%s)\n", "Reading command packet length failed: %d (%s)\n",
@ -280,7 +281,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
length_remaining, sizeof(mms->in_buffer) - 12); length_remaining, sizeof(mms->in_buffer) - 12);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
read_result = url_read_complete(mms->mms_hd, mms->in_buffer + 12, read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer + 12,
length_remaining) ; length_remaining) ;
if (read_result != length_remaining) { if (read_result != length_remaining) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
@ -318,7 +319,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
} }
mms->remaining_in_len = length_remaining; mms->remaining_in_len = length_remaining;
mms->read_in_ptr = mms->in_buffer; mms->read_in_ptr = mms->in_buffer;
read_result= url_read_complete(mms->mms_hd, mms->in_buffer, length_remaining); read_result= ffurl_read_complete(mms->mms_hd, mms->in_buffer, length_remaining);
if(read_result != length_remaining) { if(read_result != length_remaining) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
"Failed to read packet data of size %d: %d (%s)\n", "Failed to read packet data of size %d: %d (%s)\n",
@ -463,7 +464,7 @@ static int mms_close(URLContext *h)
MMSContext *mms = &mmst->mms; MMSContext *mms = &mmst->mms;
if(mms->mms_hd) { if(mms->mms_hd) {
send_close_packet(mmst); send_close_packet(mmst);
url_close(mms->mms_hd); ffurl_close(mms->mms_hd);
} }
/* free all separately allocated pointers in mms */ /* free all separately allocated pointers in mms */
@ -522,7 +523,7 @@ static int mms_open(URLContext *h, const char *uri, int flags)
// establish tcp connection. // establish tcp connection.
ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL);
err = url_open(&mms->mms_hd, tcpname, URL_RDWR); err = ffurl_open(&mms->mms_hd, tcpname, URL_RDWR);
if (err) if (err)
goto fail; goto fail;

View File

@ -25,6 +25,7 @@
#include "rtmppkt.h" #include "rtmppkt.h"
#include "flv.h" #include "flv.h"
#include "url.h"
void ff_amf_write_bool(uint8_t **dst, int val) void ff_amf_write_bool(uint8_t **dst, int val)
{ {
@ -78,14 +79,14 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
enum RTMPPacketType type; enum RTMPPacketType type;
int size = 0; int size = 0;
if (url_read(h, &hdr, 1) != 1) if (ffurl_read(h, &hdr, 1) != 1)
return AVERROR(EIO); return AVERROR(EIO);
size++; size++;
channel_id = hdr & 0x3F; channel_id = hdr & 0x3F;
if (channel_id < 2) { //special case for channel number >= 64 if (channel_id < 2) { //special case for channel number >= 64
buf[1] = 0; buf[1] = 0;
if (url_read_complete(h, buf, channel_id + 1) != channel_id + 1) if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1)
return AVERROR(EIO); return AVERROR(EIO);
size += channel_id + 1; size += channel_id + 1;
channel_id = AV_RL16(buf) + 64; channel_id = AV_RL16(buf) + 64;
@ -98,28 +99,28 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
if (hdr == RTMP_PS_ONEBYTE) { if (hdr == RTMP_PS_ONEBYTE) {
timestamp = prev_pkt[channel_id].ts_delta; timestamp = prev_pkt[channel_id].ts_delta;
} else { } else {
if (url_read_complete(h, buf, 3) != 3) if (ffurl_read_complete(h, buf, 3) != 3)
return AVERROR(EIO); return AVERROR(EIO);
size += 3; size += 3;
timestamp = AV_RB24(buf); timestamp = AV_RB24(buf);
if (hdr != RTMP_PS_FOURBYTES) { if (hdr != RTMP_PS_FOURBYTES) {
if (url_read_complete(h, buf, 3) != 3) if (ffurl_read_complete(h, buf, 3) != 3)
return AVERROR(EIO); return AVERROR(EIO);
size += 3; size += 3;
data_size = AV_RB24(buf); data_size = AV_RB24(buf);
if (url_read_complete(h, buf, 1) != 1) if (ffurl_read_complete(h, buf, 1) != 1)
return AVERROR(EIO); return AVERROR(EIO);
size++; size++;
type = buf[0]; type = buf[0];
if (hdr == RTMP_PS_TWELVEBYTES) { if (hdr == RTMP_PS_TWELVEBYTES) {
if (url_read_complete(h, buf, 4) != 4) if (ffurl_read_complete(h, buf, 4) != 4)
return AVERROR(EIO); return AVERROR(EIO);
size += 4; size += 4;
extra = AV_RL32(buf); extra = AV_RL32(buf);
} }
} }
if (timestamp == 0xFFFFFF) { if (timestamp == 0xFFFFFF) {
if (url_read_complete(h, buf, 4) != 4) if (ffurl_read_complete(h, buf, 4) != 4)
return AVERROR(EIO); return AVERROR(EIO);
timestamp = AV_RB32(buf); timestamp = AV_RB32(buf);
} }
@ -139,7 +140,7 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
prev_pkt[channel_id].extra = extra; prev_pkt[channel_id].extra = extra;
while (data_size > 0) { while (data_size > 0) {
int toread = FFMIN(data_size, chunk_size); int toread = FFMIN(data_size, chunk_size);
if (url_read_complete(h, p->data + offset, toread) != toread) { if (ffurl_read_complete(h, p->data + offset, toread) != toread) {
ff_rtmp_packet_destroy(p); ff_rtmp_packet_destroy(p);
return AVERROR(EIO); return AVERROR(EIO);
} }
@ -147,7 +148,7 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
offset += chunk_size; offset += chunk_size;
size += chunk_size; size += chunk_size;
if (data_size > 0) { if (data_size > 0) {
url_read_complete(h, &t, 1); //marker ffurl_read_complete(h, &t, 1); //marker
size++; size++;
if (t != (0xC0 + channel_id)) if (t != (0xC0 + channel_id))
return -1; return -1;
@ -214,15 +215,15 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
} }
prev_pkt[pkt->channel_id].extra = pkt->extra; prev_pkt[pkt->channel_id].extra = pkt->extra;
url_write(h, pkt_hdr, p-pkt_hdr); ffurl_write(h, pkt_hdr, p-pkt_hdr);
size = p - pkt_hdr + pkt->data_size; size = p - pkt_hdr + pkt->data_size;
while (off < pkt->data_size) { while (off < pkt->data_size) {
int towrite = FFMIN(chunk_size, pkt->data_size - off); int towrite = FFMIN(chunk_size, pkt->data_size - off);
url_write(h, pkt->data + off, towrite); ffurl_write(h, pkt->data + off, towrite);
off += towrite; off += towrite;
if (off < pkt->data_size) { if (off < pkt->data_size) {
uint8_t marker = 0xC0 | pkt->channel_id; uint8_t marker = 0xC0 | pkt->channel_id;
url_write(h, &marker, 1); ffurl_write(h, &marker, 1);
size++; size++;
} }
} }

View File

@ -36,6 +36,7 @@
#include "flv.h" #include "flv.h"
#include "rtmp.h" #include "rtmp.h"
#include "rtmppkt.h" #include "rtmppkt.h"
#include "url.h"
/* we can't use av_log() with URLContext yet... */ /* we can't use av_log() with URLContext yet... */
#if FF_API_URL_CLASS #if FF_API_URL_CLASS
@ -485,13 +486,13 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
tosend[i] = av_lfg_get(&rnd) >> 24; tosend[i] = av_lfg_get(&rnd) >> 24;
client_pos = rtmp_handshake_imprint_with_digest(tosend + 1); client_pos = rtmp_handshake_imprint_with_digest(tosend + 1);
url_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE + 1); ffurl_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE + 1);
i = url_read_complete(rt->stream, serverdata, RTMP_HANDSHAKE_PACKET_SIZE + 1); i = ffurl_read_complete(rt->stream, serverdata, RTMP_HANDSHAKE_PACKET_SIZE + 1);
if (i != RTMP_HANDSHAKE_PACKET_SIZE + 1) { if (i != RTMP_HANDSHAKE_PACKET_SIZE + 1) {
av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
return -1; return -1;
} }
i = url_read_complete(rt->stream, clientdata, RTMP_HANDSHAKE_PACKET_SIZE); i = ffurl_read_complete(rt->stream, clientdata, RTMP_HANDSHAKE_PACKET_SIZE);
if (i != RTMP_HANDSHAKE_PACKET_SIZE) { if (i != RTMP_HANDSHAKE_PACKET_SIZE) {
av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
return -1; return -1;
@ -531,9 +532,9 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32); tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
// write reply back to the server // write reply back to the server
url_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE); ffurl_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE);
} else { } else {
url_write(rt->stream, serverdata+1, RTMP_HANDSHAKE_PACKET_SIZE); ffurl_write(rt->stream, serverdata+1, RTMP_HANDSHAKE_PACKET_SIZE);
} }
return 0; return 0;
@ -785,7 +786,7 @@ static int rtmp_close(URLContext *h)
gen_delete_stream(h, rt); gen_delete_stream(h, rt);
av_freep(&rt->flv_data); av_freep(&rt->flv_data);
url_close(rt->stream); ffurl_close(rt->stream);
av_free(rt); av_free(rt);
return 0; return 0;
} }
@ -820,7 +821,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
port = RTMP_DEFAULT_PORT; port = RTMP_DEFAULT_PORT;
ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
if (url_open(&rt->stream, buf, URL_RDWR) < 0) { if (ffurl_open(&rt->stream, buf, URL_RDWR) < 0) {
av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot open connection %s\n", buf); av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot open connection %s\n", buf);
goto fail; goto fail;
} }
@ -887,7 +888,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
rt->flv_off = 0; rt->flv_off = 0;
} }
s->max_packet_size = url_get_max_packet_size(rt->stream); s->max_packet_size = rt->stream->max_packet_size;
s->is_streamed = 1; s->is_streamed = 1;
return 0; return 0;

View File

@ -25,6 +25,7 @@
#include "libavcodec/get_bits.h" #include "libavcodec/get_bits.h"
#include "avformat.h" #include "avformat.h"
#include "mpegts.h" #include "mpegts.h"
#include "url.h"
#include <unistd.h> #include <unistd.h>
#include <strings.h> #include <strings.h>
@ -325,8 +326,8 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
if ((len > 0) && buf) { if ((len > 0) && buf) {
int result; int result;
av_dlog(s->ic, "sending %d bytes of RR\n", len); av_dlog(s->ic, "sending %d bytes of RR\n", len);
result= url_write(s->rtp_ctx, buf, len); result= ffurl_write(s->rtp_ctx, buf, len);
av_dlog(s->ic, "result from url_write: %d\n", result); av_dlog(s->ic, "result from ffurl_write: %d\n", result);
av_free(buf); av_free(buf);
} }
return 0; return 0;
@ -351,7 +352,7 @@ void rtp_send_punch_packets(URLContext* rtp_handle)
avio_flush(pb); avio_flush(pb);
len = avio_close_dyn_buf(pb, &buf); len = avio_close_dyn_buf(pb, &buf);
if ((len > 0) && buf) if ((len > 0) && buf)
url_write(rtp_handle, buf, len); ffurl_write(rtp_handle, buf, len);
av_free(buf); av_free(buf);
/* Send a minimal RTCP RR */ /* Send a minimal RTCP RR */
@ -366,7 +367,7 @@ void rtp_send_punch_packets(URLContext* rtp_handle)
avio_flush(pb); avio_flush(pb);
len = avio_close_dyn_buf(pb, &buf); len = avio_close_dyn_buf(pb, &buf);
if ((len > 0) && buf) if ((len > 0) && buf)
url_write(rtp_handle, buf, len); ffurl_write(rtp_handle, buf, len);
av_free(buf); av_free(buf);
} }

View File

@ -29,6 +29,7 @@
#include "avformat.h" #include "avformat.h"
#include "avio_internal.h" #include "avio_internal.h"
#include "rtpdec.h" #include "rtpdec.h"
#include "url.h"
#include <unistd.h> #include <unistd.h>
#include <stdarg.h> #include <stdarg.h>
@ -189,7 +190,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
build_udp_url(buf, sizeof(buf), build_udp_url(buf, sizeof(buf),
hostname, rtp_port, local_rtp_port, ttl, max_packet_size, hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
connect); connect);
if (url_open(&s->rtp_hd, buf, flags) < 0) if (ffurl_open(&s->rtp_hd, buf, flags) < 0)
goto fail; goto fail;
if (local_rtp_port>=0 && local_rtcp_port<0) if (local_rtp_port>=0 && local_rtcp_port<0)
local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1; local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1;
@ -197,23 +198,23 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
build_udp_url(buf, sizeof(buf), build_udp_url(buf, sizeof(buf),
hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size, hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
connect); connect);
if (url_open(&s->rtcp_hd, buf, flags) < 0) if (ffurl_open(&s->rtcp_hd, buf, flags) < 0)
goto fail; goto fail;
/* just to ease handle access. XXX: need to suppress direct handle /* just to ease handle access. XXX: need to suppress direct handle
access */ access */
s->rtp_fd = url_get_file_handle(s->rtp_hd); s->rtp_fd = ffurl_get_file_handle(s->rtp_hd);
s->rtcp_fd = url_get_file_handle(s->rtcp_hd); s->rtcp_fd = ffurl_get_file_handle(s->rtcp_hd);
h->max_packet_size = url_get_max_packet_size(s->rtp_hd); h->max_packet_size = s->rtp_hd->max_packet_size;
h->is_streamed = 1; h->is_streamed = 1;
return 0; return 0;
fail: fail:
if (s->rtp_hd) if (s->rtp_hd)
url_close(s->rtp_hd); ffurl_close(s->rtp_hd);
if (s->rtcp_hd) if (s->rtcp_hd)
url_close(s->rtcp_hd); ffurl_close(s->rtcp_hd);
av_free(s); av_free(s);
return AVERROR(EIO); return AVERROR(EIO);
} }
@ -296,7 +297,7 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
hd = s->rtp_hd; hd = s->rtp_hd;
} }
ret = url_write(hd, buf, size); ret = ffurl_write(hd, buf, size);
#if 0 #if 0
{ {
struct timespec ts; struct timespec ts;
@ -312,8 +313,8 @@ static int rtp_close(URLContext *h)
{ {
RTPContext *s = h->priv_data; RTPContext *s = h->priv_data;
url_close(s->rtp_hd); ffurl_close(s->rtp_hd);
url_close(s->rtcp_hd); ffurl_close(s->rtcp_hd);
av_free(s); av_free(s);
return 0; return 0;
} }

View File

@ -42,6 +42,7 @@
#include "rdt.h" #include "rdt.h"
#include "rtpdec_formats.h" #include "rtpdec_formats.h"
#include "rtpenc_chain.h" #include "rtpenc_chain.h"
#include "url.h"
//#define DEBUG //#define DEBUG
//#define DEBUG_RTP_TCP //#define DEBUG_RTP_TCP
@ -508,7 +509,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s)
} }
rtsp_st->transport_priv = NULL; rtsp_st->transport_priv = NULL;
if (rtsp_st->rtp_handle) if (rtsp_st->rtp_handle)
url_close(rtsp_st->rtp_handle); ffurl_close(rtsp_st->rtp_handle);
rtsp_st->rtp_handle = NULL; rtsp_st->rtp_handle = NULL;
} }
} }
@ -817,7 +818,7 @@ void ff_rtsp_skip_packet(AVFormatContext *s)
int ret, len, len1; int ret, len, len1;
uint8_t buf[1024]; uint8_t buf[1024];
ret = url_read_complete(rt->rtsp_hd, buf, 3); ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
if (ret != 3) if (ret != 3)
return; return;
len = AV_RB16(buf + 1); len = AV_RB16(buf + 1);
@ -829,7 +830,7 @@ void ff_rtsp_skip_packet(AVFormatContext *s)
len1 = len; len1 = len;
if (len1 > sizeof(buf)) if (len1 > sizeof(buf))
len1 = sizeof(buf); len1 = sizeof(buf);
ret = url_read_complete(rt->rtsp_hd, buf, len1); ret = ffurl_read_complete(rt->rtsp_hd, buf, len1);
if (ret != len1) if (ret != len1)
return; return;
len -= len1; len -= len1;
@ -854,7 +855,7 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
for (;;) { for (;;) {
q = buf; q = buf;
for (;;) { for (;;) {
ret = url_read_complete(rt->rtsp_hd, &ch, 1); ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
#ifdef DEBUG_RTP_TCP #ifdef DEBUG_RTP_TCP
av_dlog(s, "ret=%d c=%02x [%c]\n", ret, ch, ch); av_dlog(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
#endif #endif
@ -902,7 +903,7 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
if (content_length > 0) { if (content_length > 0) {
/* leave some room for a trailing '\0' (useful for simple parsing) */ /* leave some room for a trailing '\0' (useful for simple parsing) */
content = av_malloc(content_length + 1); content = av_malloc(content_length + 1);
(void)url_read_complete(rt->rtsp_hd, content, content_length); ffurl_read_complete(rt->rtsp_hd, content, content_length);
content[content_length] = '\0'; content[content_length] = '\0';
} }
if (content_ptr) if (content_ptr)
@ -982,14 +983,14 @@ static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
av_dlog(s, "Sending:\n%s--\n", buf); av_dlog(s, "Sending:\n%s--\n", buf);
url_write(rt->rtsp_hd_out, out_buf, strlen(out_buf)); ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
if (send_content_length > 0 && send_content) { if (send_content_length > 0 && send_content) {
if (rt->control_transport == RTSP_MODE_TUNNEL) { if (rt->control_transport == RTSP_MODE_TUNNEL) {
av_log(s, AV_LOG_ERROR, "tunneling of RTSP requests " av_log(s, AV_LOG_ERROR, "tunneling of RTSP requests "
"with content data not supported\n"); "with content data not supported\n");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
url_write(rt->rtsp_hd_out, send_content, send_content_length); ffurl_write(rt->rtsp_hd_out, send_content, send_content_length);
} }
rt->last_cmd_time = av_gettime(); rt->last_cmd_time = av_gettime();
@ -1115,14 +1116,14 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
"?localport=%d", j); "?localport=%d", j);
/* we will use two ports per rtp stream (rtp and rtcp) */ /* we will use two ports per rtp stream (rtp and rtcp) */
j += 2; j += 2;
if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) if (ffurl_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0)
goto rtp_opened; goto rtp_opened;
} }
} }
#if 0 #if 0
/* then try on any port */ /* then try on any port */
if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) { if (ffurl_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
err = AVERROR_INVALIDDATA; err = AVERROR_INVALIDDATA;
goto fail; goto fail;
} }
@ -1268,7 +1269,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL, namebuf, ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
port, "?ttl=%d", ttl); port, "?ttl=%d", ttl);
if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { if (ffurl_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
err = AVERROR_INVALIDDATA; err = AVERROR_INVALIDDATA;
goto fail; goto fail;
} }
@ -1296,8 +1297,8 @@ fail:
void ff_rtsp_close_connections(AVFormatContext *s) void ff_rtsp_close_connections(AVFormatContext *s)
{ {
RTSPState *rt = s->priv_data; RTSPState *rt = s->priv_data;
if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out); if (rt->rtsp_hd_out != rt->rtsp_hd) ffurl_close(rt->rtsp_hd_out);
url_close(rt->rtsp_hd); ffurl_close(rt->rtsp_hd);
rt->rtsp_hd = rt->rtsp_hd_out = NULL; rt->rtsp_hd = rt->rtsp_hd_out = NULL;
} }
@ -1395,7 +1396,7 @@ redirect:
av_get_random_seed(), av_get_random_seed()); av_get_random_seed(), av_get_random_seed());
/* GET requests */ /* GET requests */
if (url_alloc(&rt->rtsp_hd, httpname, URL_RDONLY) < 0) { if (ffurl_alloc(&rt->rtsp_hd, httpname, URL_RDONLY) < 0) {
err = AVERROR(EIO); err = AVERROR(EIO);
goto fail; goto fail;
} }
@ -1410,13 +1411,13 @@ redirect:
ff_http_set_headers(rt->rtsp_hd, headers); ff_http_set_headers(rt->rtsp_hd, headers);
/* complete the connection */ /* complete the connection */
if (url_connect(rt->rtsp_hd)) { if (ffurl_connect(rt->rtsp_hd)) {
err = AVERROR(EIO); err = AVERROR(EIO);
goto fail; goto fail;
} }
/* POST requests */ /* POST requests */
if (url_alloc(&rt->rtsp_hd_out, httpname, URL_WRONLY) < 0 ) { if (ffurl_alloc(&rt->rtsp_hd_out, httpname, URL_WRONLY) < 0 ) {
err = AVERROR(EIO); err = AVERROR(EIO);
goto fail; goto fail;
} }
@ -1452,14 +1453,14 @@ redirect:
ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd); ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd);
/* complete the connection */ /* complete the connection */
if (url_connect(rt->rtsp_hd_out)) { if (ffurl_connect(rt->rtsp_hd_out)) {
err = AVERROR(EIO); err = AVERROR(EIO);
goto fail; goto fail;
} }
} else { } else {
/* open the tcp connection */ /* open the tcp connection */
ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL); ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL);
if (url_open(&rt->rtsp_hd, tcpname, URL_RDWR) < 0) { if (ffurl_open(&rt->rtsp_hd, tcpname, URL_RDWR) < 0) {
err = AVERROR(EIO); err = AVERROR(EIO);
goto fail; goto fail;
} }
@ -1467,7 +1468,7 @@ redirect:
} }
rt->seq = 0; rt->seq = 0;
tcp_fd = url_get_file_handle(rt->rtsp_hd); tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) { if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host), getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
NULL, 0, NI_NUMERICHOST); NULL, 0, NI_NUMERICHOST);
@ -1570,7 +1571,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
return AVERROR(EAGAIN); return AVERROR(EAGAIN);
max_p = 0; max_p = 0;
if (rt->rtsp_hd) { if (rt->rtsp_hd) {
tcp_fd = url_get_file_handle(rt->rtsp_hd); tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
p[max_p].fd = tcp_fd; p[max_p].fd = tcp_fd;
p[max_p++].events = POLLIN; p[max_p++].events = POLLIN;
} else { } else {
@ -1579,7 +1580,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
for (i = 0; i < rt->nb_rtsp_streams; i++) { for (i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i]; rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) { if (rtsp_st->rtp_handle) {
p[max_p].fd = url_get_file_handle(rtsp_st->rtp_handle); p[max_p].fd = ffurl_get_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN; p[max_p++].events = POLLIN;
p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle); p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN; p[max_p++].events = POLLIN;
@ -1593,7 +1594,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
rtsp_st = rt->rtsp_streams[i]; rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) { if (rtsp_st->rtp_handle) {
if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) { if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
ret = url_read(rtsp_st->rtp_handle, buf, buf_size); ret = ffurl_read(rtsp_st->rtp_handle, buf, buf_size);
if (ret > 0) { if (ret > 0) {
*prtsp_st = rtsp_st; *prtsp_st = rtsp_st;
return ret; return ret;
@ -1806,7 +1807,7 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap)
namebuf, rtsp_st->sdp_port, namebuf, rtsp_st->sdp_port,
"?localport=%d&ttl=%d", rtsp_st->sdp_port, "?localport=%d&ttl=%d", rtsp_st->sdp_port,
rtsp_st->sdp_ttl); rtsp_st->sdp_ttl);
if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { if (ffurl_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
err = AVERROR_INVALIDDATA; err = AVERROR_INVALIDDATA;
goto fail; goto fail;
} }
@ -1862,12 +1863,12 @@ static int rtp_read_header(AVFormatContext *s,
if (!ff_network_init()) if (!ff_network_init())
return AVERROR(EIO); return AVERROR(EIO);
ret = url_open(&in, s->filename, URL_RDONLY); ret = ffurl_open(&in, s->filename, URL_RDONLY);
if (ret) if (ret)
goto fail; goto fail;
while (1) { while (1) {
ret = url_read(in, recvbuf, sizeof(recvbuf)); ret = ffurl_read(in, recvbuf, sizeof(recvbuf));
if (ret == AVERROR(EAGAIN)) if (ret == AVERROR(EAGAIN))
continue; continue;
if (ret < 0) if (ret < 0)
@ -1886,8 +1887,8 @@ static int rtp_read_header(AVFormatContext *s,
payload_type = recvbuf[1] & 0x7f; payload_type = recvbuf[1] & 0x7f;
break; break;
} }
getsockname(url_get_file_handle(in), (struct sockaddr*) &addr, &addrlen); getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
url_close(in); ffurl_close(in);
in = NULL; in = NULL;
memset(&codec, 0, sizeof(codec)); memset(&codec, 0, sizeof(codec));
@ -1926,7 +1927,7 @@ static int rtp_read_header(AVFormatContext *s,
fail: fail:
if (in) if (in)
url_close(in); ffurl_close(in);
ff_network_close(); ff_network_close();
return ret; return ret;
} }

View File

@ -28,6 +28,7 @@
#include "os_support.h" #include "os_support.h"
#include "rtsp.h" #include "rtsp.h"
#include "rdt.h" #include "rdt.h"
#include "url.h"
//#define DEBUG //#define DEBUG
//#define DEBUG_RTP_TCP //#define DEBUG_RTP_TCP
@ -200,7 +201,7 @@ redo:
if (rt->state != RTSP_STATE_STREAMING) if (rt->state != RTSP_STATE_STREAMING)
return 0; return 0;
} }
ret = url_read_complete(rt->rtsp_hd, buf, 3); ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
if (ret != 3) if (ret != 3)
return -1; return -1;
id = buf[0]; id = buf[0];
@ -211,7 +212,7 @@ redo:
if (len > buf_size || len < 12) if (len > buf_size || len < 12)
goto redo; goto redo;
/* get the data */ /* get the data */
ret = url_read_complete(rt->rtsp_hd, buf, len); ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
if (ret != len) if (ret != len)
return -1; return -1;
if (rt->transport == RTSP_TRANSPORT_RDT && if (rt->transport == RTSP_TRANSPORT_RDT &&

View File

@ -32,6 +32,7 @@
#include "avio_internal.h" #include "avio_internal.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "url.h"
#define SDP_MAX_SIZE 16384 #define SDP_MAX_SIZE 16384
@ -158,7 +159,7 @@ static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
interleave_header[0] = '$'; interleave_header[0] = '$';
interleave_header[1] = id; interleave_header[1] = id;
AV_WB16(interleave_header + 2, packet_len); AV_WB16(interleave_header + 2, packet_len);
url_write(rt->rtsp_hd_out, interleaved_packet, 4 + packet_len); ffurl_write(rt->rtsp_hd_out, interleaved_packet, 4 + packet_len);
ptr += packet_len; ptr += packet_len;
size -= packet_len; size -= packet_len;
} }
@ -172,7 +173,7 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
RTSPState *rt = s->priv_data; RTSPState *rt = s->priv_data;
RTSPStream *rtsp_st; RTSPStream *rtsp_st;
int n; int n;
struct pollfd p = {url_get_file_handle(rt->rtsp_hd), POLLIN, 0}; struct pollfd p = {ffurl_get_file_handle(rt->rtsp_hd), POLLIN, 0};
AVFormatContext *rtpctx; AVFormatContext *rtpctx;
int ret; int ret;

View File

@ -26,6 +26,7 @@
#include "os_support.h" #include "os_support.h"
#include "internal.h" #include "internal.h"
#include "avio_internal.h" #include "avio_internal.h"
#include "url.h"
#if HAVE_POLL_H #if HAVE_POLL_H
#include <poll.h> #include <poll.h>
#endif #endif
@ -53,7 +54,7 @@ static int sap_read_close(AVFormatContext *s)
if (sap->sdp_ctx) if (sap->sdp_ctx)
av_close_input_stream(sap->sdp_ctx); av_close_input_stream(sap->sdp_ctx);
if (sap->ann_fd) if (sap->ann_fd)
url_close(sap->ann_fd); ffurl_close(sap->ann_fd);
av_freep(&sap->sdp); av_freep(&sap->sdp);
ff_network_close(); ff_network_close();
return 0; return 0;
@ -84,7 +85,7 @@ static int sap_read_header(AVFormatContext *s,
ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d", ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d",
port); port);
ret = url_open(&sap->ann_fd, url, URL_RDONLY); ret = ffurl_open(&sap->ann_fd, url, URL_RDONLY);
if (ret) if (ret)
goto fail; goto fail;
@ -92,7 +93,7 @@ static int sap_read_header(AVFormatContext *s,
int addr_type, auth_len; int addr_type, auth_len;
int pos; int pos;
ret = url_read(sap->ann_fd, recvbuf, sizeof(recvbuf) - 1); ret = ffurl_read(sap->ann_fd, recvbuf, sizeof(recvbuf) - 1);
if (ret == AVERROR(EAGAIN)) if (ret == AVERROR(EAGAIN))
continue; continue;
if (ret < 0) if (ret < 0)
@ -182,7 +183,7 @@ fail:
static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt) static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
{ {
struct SAPState *sap = s->priv_data; struct SAPState *sap = s->priv_data;
int fd = url_get_file_handle(sap->ann_fd); int fd = ffurl_get_file_handle(sap->ann_fd);
int n, ret; int n, ret;
struct pollfd p = {fd, POLLIN, 0}; struct pollfd p = {fd, POLLIN, 0};
uint8_t recvbuf[1500]; uint8_t recvbuf[1500];
@ -194,7 +195,7 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
n = poll(&p, 1, 0); n = poll(&p, 1, 0);
if (n <= 0 || !(p.revents & POLLIN)) if (n <= 0 || !(p.revents & POLLIN))
break; break;
ret = url_read(sap->ann_fd, recvbuf, sizeof(recvbuf)); ret = ffurl_read(sap->ann_fd, recvbuf, sizeof(recvbuf));
if (ret >= 8) { if (ret >= 8) {
uint16_t hash = AV_RB16(&recvbuf[2]); uint16_t hash = AV_RB16(&recvbuf[2]);
/* Should ideally check the source IP address, too */ /* Should ideally check the source IP address, too */

View File

@ -28,6 +28,7 @@
#include "network.h" #include "network.h"
#include "os_support.h" #include "os_support.h"
#include "rtpenc_chain.h" #include "rtpenc_chain.h"
#include "url.h"
struct SAPState { struct SAPState {
uint8_t *ann; uint8_t *ann;
@ -53,12 +54,12 @@ static int sap_write_close(AVFormatContext *s)
if (sap->last_time && sap->ann && sap->ann_fd) { if (sap->last_time && sap->ann && sap->ann_fd) {
sap->ann[0] |= 4; /* Session deletion*/ sap->ann[0] |= 4; /* Session deletion*/
url_write(sap->ann_fd, sap->ann, sap->ann_size); ffurl_write(sap->ann_fd, sap->ann, sap->ann_size);
} }
av_freep(&sap->ann); av_freep(&sap->ann);
if (sap->ann_fd) if (sap->ann_fd)
url_close(sap->ann_fd); ffurl_close(sap->ann_fd);
ff_network_close(); ff_network_close();
return 0; return 0;
} }
@ -145,7 +146,7 @@ static int sap_write_header(AVFormatContext *s)
"?ttl=%d", ttl); "?ttl=%d", ttl);
if (!same_port) if (!same_port)
base_port += 2; base_port += 2;
ret = url_open(&fd, url, URL_WRONLY); ret = ffurl_open(&fd, url, URL_WRONLY);
if (ret) { if (ret) {
ret = AVERROR(EIO); ret = AVERROR(EIO);
goto fail; goto fail;
@ -157,13 +158,13 @@ static int sap_write_header(AVFormatContext *s)
ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port, ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port,
"?ttl=%d&connect=1", ttl); "?ttl=%d&connect=1", ttl);
ret = url_open(&sap->ann_fd, url, URL_WRONLY); ret = ffurl_open(&sap->ann_fd, url, URL_WRONLY);
if (ret) { if (ret) {
ret = AVERROR(EIO); ret = AVERROR(EIO);
goto fail; goto fail;
} }
udp_fd = url_get_file_handle(sap->ann_fd); udp_fd = ffurl_get_file_handle(sap->ann_fd);
if (getsockname(udp_fd, (struct sockaddr*) &localaddr, &addrlen)) { if (getsockname(udp_fd, (struct sockaddr*) &localaddr, &addrlen)) {
ret = AVERROR(EIO); ret = AVERROR(EIO);
goto fail; goto fail;
@ -217,7 +218,7 @@ static int sap_write_header(AVFormatContext *s)
pos += strlen(&sap->ann[pos]); pos += strlen(&sap->ann[pos]);
sap->ann_size = pos; sap->ann_size = pos;
if (sap->ann_size > url_get_max_packet_size(sap->ann_fd)) { if (sap->ann_size > sap->ann_fd->max_packet_size) {
av_log(s, AV_LOG_ERROR, "Announcement too large to send in one " av_log(s, AV_LOG_ERROR, "Announcement too large to send in one "
"packet\n"); "packet\n");
goto fail; goto fail;
@ -238,7 +239,7 @@ static int sap_write_packet(AVFormatContext *s, AVPacket *pkt)
int64_t now = av_gettime(); int64_t now = av_gettime();
if (!sap->last_time || now - sap->last_time > 5000000) { if (!sap->last_time || now - sap->last_time > 5000000) {
int ret = url_write(sap->ann_fd, sap->ann, sap->ann_size); int ret = ffurl_write(sap->ann_fd, sap->ann, sap->ann_size);
/* Don't abort even if we get "Destination unreachable" */ /* Don't abort even if we get "Destination unreachable" */
if (ret < 0 && ret != AVERROR(ECONNREFUSED)) if (ret < 0 && ret != AVERROR(ECONNREFUSED))
return ret; return ret;

129
libavformat/url.h Normal file
View File

@ -0,0 +1,129 @@
/*
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* unbuffered private I/O API
*/
#ifndef AVFORMAT_URL_H
#define AVFORMAT_URL_H
#include "avio.h"
/**
* Create a URLContext for accessing to the resource indicated by
* url, but do not initiate the connection yet.
*
* @param puc pointer to the location where, in case of success, the
* function puts the pointer to the created URLContext
* @param flags flags which control how the resource indicated by url
* is to be opened
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int ffurl_alloc(URLContext **h, const char *url, int flags);
/**
* Connect an URLContext that has been allocated by ffurl_alloc
*/
int ffurl_connect(URLContext *h);
/**
* Create an URLContext for accessing to the resource indicated by
* url, and open it.
*
* @param puc pointer to the location where, in case of success, the
* function puts the pointer to the created URLContext
* @param flags flags which control how the resource indicated by url
* is to be opened
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int ffurl_open(URLContext **h, const char *url, int flags);
/**
* Read up to size bytes from the resource accessed by h, and store
* the read bytes in buf.
*
* @return The number of bytes actually read, or a negative value
* corresponding to an AVERROR code in case of error. A value of zero
* indicates that it is not possible to read more from the accessed
* resource (except if the value of the size argument is also zero).
*/
int ffurl_read(URLContext *h, unsigned char *buf, int size);
/**
* Read as many bytes as possible (up to size), calling the
* read function multiple times if necessary.
* This makes special short-read handling in applications
* unnecessary, if the return value is < size then it is
* certain there was either an error or the end of file was reached.
*/
int ffurl_read_complete(URLContext *h, unsigned char *buf, int size);
/**
* Write size bytes from buf to the resource accessed by h.
*
* @return the number of bytes actually written, or a negative value
* corresponding to an AVERROR code in case of failure
*/
int ffurl_write(URLContext *h, const unsigned char *buf, int size);
/**
* Change the position that will be used by the next read/write
* operation on the resource accessed by h.
*
* @param pos specifies the new position to set
* @param whence specifies how pos should be interpreted, it must be
* one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the
* current position), SEEK_END (seek from the end), or AVSEEK_SIZE
* (return the filesize of the requested resource, pos is ignored).
* @return a negative value corresponding to an AVERROR code in case
* of failure, or the resulting file position, measured in bytes from
* the beginning of the file. You can use this feature together with
* SEEK_CUR to read the current file position.
*/
int64_t ffurl_seek(URLContext *h, int64_t pos, int whence);
/**
* Close the resource accessed by the URLContext h, and free the
* memory used by it.
*
* @return a negative value if an error condition occurred, 0
* otherwise
*/
int ffurl_close(URLContext *h);
/**
* Return the filesize of the resource accessed by h, AVERROR(ENOSYS)
* if the operation is not supported by h, or another negative value
* corresponding to an AVERROR error code in case of failure.
*/
int64_t ffurl_size(URLContext *h);
/**
* Return the file descriptor associated with this URL. For RTP, this
* will return only the RTP file descriptor, not the RTCP file descriptor.
*
* @return the file descriptor associated with this URL, or <0 on error.
*/
int ffurl_get_file_handle(URLContext *h);
#endif //AVFORMAT_URL_H

View File

@ -1,2 +1,2 @@
408f47ee5a60866fc751f7bc2314cbd6 *./tests/data/acodec/ac3.rm 5ddb6d25dd117db29627f9d286153a7a *./tests/data/acodec/ac3.rm
98751 ./tests/data/acodec/ac3.rm 98751 ./tests/data/acodec/ac3.rm

View File

@ -1,2 +1,2 @@
da74fe749c2eb21bbead7de81d2f3078 *./tests/data/lavf/lavf.rm a1c71456f21d5459d2824d75bbdcc80c *./tests/data/lavf/lavf.rm
346706 ./tests/data/lavf/lavf.rm 346706 ./tests/data/lavf/lavf.rm

View File

@ -5,7 +5,8 @@ ret:-1 st:-1 flags:1 ts: 1.894167
ret:-1 st: 0 flags:0 ts: 0.788000 ret:-1 st: 0 flags:0 ts: 0.788000
ret: 0 st: 0 flags:1 ts:-0.317000 ret: 0 st: 0 flags:1 ts:-0.317000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
ret:-1 st:-1 flags:0 ts: 2.576668 ret: 0 st:-1 flags:0 ts: 2.576668
ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 42397 size: 558
ret:-1 st:-1 flags:1 ts: 1.470835 ret:-1 st:-1 flags:1 ts: 1.470835
ret:-1 st: 0 flags:0 ts: 0.365000 ret:-1 st: 0 flags:0 ts: 0.365000
ret: 0 st: 0 flags:1 ts:-0.741000 ret: 0 st: 0 flags:1 ts:-0.741000
@ -19,7 +20,8 @@ ret:-1 st:-1 flags:0 ts: 1.730004
ret:-1 st:-1 flags:1 ts: 0.624171 ret:-1 st:-1 flags:1 ts: 0.624171
ret: 0 st: 0 flags:0 ts:-0.482000 ret: 0 st: 0 flags:0 ts:-0.482000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
ret:-1 st: 0 flags:1 ts: 2.413000 ret: 0 st: 0 flags:1 ts: 2.413000
ret: 0 st: 0 flags:1 dts: 2.368000 pts: 2.368000 pos: 38981 size: 558
ret:-1 st:-1 flags:0 ts: 1.306672 ret:-1 st:-1 flags:0 ts: 1.306672
ret:-1 st:-1 flags:1 ts: 0.200839 ret:-1 st:-1 flags:1 ts: 0.200839
ret: 0 st: 0 flags:0 ts:-0.905000 ret: 0 st: 0 flags:0 ts:-0.905000
@ -28,7 +30,8 @@ ret:-1 st: 0 flags:1 ts: 1.989000
ret:-1 st:-1 flags:0 ts: 0.883340 ret:-1 st:-1 flags:0 ts: 0.883340
ret: 0 st:-1 flags:1 ts:-0.222493 ret: 0 st:-1 flags:1 ts:-0.222493
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
ret:-1 st: 0 flags:0 ts: 2.672000 ret: 0 st: 0 flags:0 ts: 2.672000
ret: 0 st: 0 flags:1 dts: 2.821000 pts: 2.821000 pos: 46383 size: 556
ret:-1 st: 0 flags:1 ts: 1.566000 ret:-1 st: 0 flags:1 ts: 1.566000
ret:-1 st:-1 flags:0 ts: 0.460008 ret:-1 st:-1 flags:0 ts: 0.460008
ret: 0 st:-1 flags:1 ts:-0.645825 ret: 0 st:-1 flags:1 ts:-0.645825