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:
commit
434f248723
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
return AVERROR_EOF;
|
||||||
* 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;
|
|
||||||
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);
|
||||||
/* Locate the segment that contains the target timestamp */
|
ret = AVERROR(EIO);
|
||||||
for (i = 0; i < var->n_segments; i++) {
|
for (i = 0; i < c->n_variants; i++) {
|
||||||
if (timestamp >= pos && timestamp < pos + var->segments[i]->duration) {
|
/* Reset reading */
|
||||||
c->cur_seq_no = var->start_seq_no + i;
|
struct variant *var = c->variants[i];
|
||||||
return 0;
|
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 */
|
||||||
|
for (j = 0; j < var->n_segments; j++) {
|
||||||
|
if (timestamp >= pos &&
|
||||||
|
timestamp < pos + var->segments[j]->duration) {
|
||||||
|
var->cur_seq_no = var->start_seq_no + j;
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += var->segments[j]->duration;
|
||||||
}
|
}
|
||||||
pos += var->segments[i]->duration;
|
|
||||||
}
|
}
|
||||||
return AVERROR(EIO);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int applehttp_probe(AVProbeData *p)
|
static int applehttp_probe(AVProbeData *p)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 = {
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 &&
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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
129
libavformat/url.h
Normal 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
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user