ffmpeg: don't pass pointer as hexadecimal string
Casting a pointer to some sort of integer and formatting it into a string isn't valid. A pointer derived from this hex string won't work reliably. Since ffmpeg doesn't provide a nice API for passing our pointer, we have to think of a different hack: ffmpeg passes the exact URL pointer to mpdurl_open(), and we can make this string part of a struct. This reduces the problem to casting the string back to the struct. This is still a workaround, but this is "sort of portable", unless the ffmpeg people start messing with the URL pointer (which would be valid according to the API definition).
This commit is contained in:
parent
e4df17f611
commit
a7888c4998
@ -50,27 +50,35 @@ typedef struct {
|
|||||||
} BasePtrs;
|
} BasePtrs;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/** hack - see url_to_base() */
|
||||||
|
char url[8];
|
||||||
|
|
||||||
struct decoder *decoder;
|
struct decoder *decoder;
|
||||||
InputStream *input;
|
InputStream *input;
|
||||||
} FopsHelper;
|
} FopsHelper;
|
||||||
|
|
||||||
static int mpdurl_open(URLContext *h, const char *filename, int flags)
|
/**
|
||||||
|
* Convert a faked mpd:// URL to a FopsHelper structure. This is a
|
||||||
|
* hack because ffmpeg does not provide a nice API for passing a
|
||||||
|
* user-defined pointer to mpdurl_open().
|
||||||
|
*/
|
||||||
|
static FopsHelper *url_to_base(const char *url)
|
||||||
{
|
{
|
||||||
uint32_t ptr;
|
union {
|
||||||
FopsHelper *base;
|
const char *in;
|
||||||
if (strlen(filename) == (8+8)) {
|
FopsHelper *out;
|
||||||
errno = 0;
|
} u = { .in = url };
|
||||||
ptr = (uint32_t) strtoll(filename + 6, NULL, 16);
|
return u.out;
|
||||||
if (errno == 0 && ptr != 0) {
|
}
|
||||||
base = (FopsHelper *) ptr;
|
|
||||||
|
static int mpdurl_open(URLContext *h, const char *filename,
|
||||||
|
mpd_unused int flags)
|
||||||
|
{
|
||||||
|
FopsHelper *base = url_to_base(filename);
|
||||||
h->priv_data = base;
|
h->priv_data = base;
|
||||||
h->is_streamed = (base->input->seekable ? 0 : 1);
|
h->is_streamed = (base->input->seekable ? 0 : 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
FATAL("Invalid format %s:%d\n", filename, flags);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mpdurl_read(URLContext *h, unsigned char *buf, int size)
|
static int mpdurl_read(URLContext *h, unsigned char *buf, int size)
|
||||||
{
|
{
|
||||||
@ -137,8 +145,9 @@ static int ffmpeg_helper(InputStream *input, int (*callback)(BasePtrs *ptrs),
|
|||||||
AVCodec *aCodec;
|
AVCodec *aCodec;
|
||||||
int ret, audioStream;
|
int ret, audioStream;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
FopsHelper fopshelp;
|
FopsHelper fopshelp = {
|
||||||
char url[24];
|
.url = "mpd://X", /* only the mpd:// prefix matters */
|
||||||
|
};
|
||||||
|
|
||||||
fopshelp.input = input;
|
fopshelp.input = input;
|
||||||
if (ptrs && ptrs->decoder) {
|
if (ptrs && ptrs->decoder) {
|
||||||
@ -148,9 +157,7 @@ static int ffmpeg_helper(InputStream *input, int (*callback)(BasePtrs *ptrs),
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ffmpeg works with ours "fileops" helper
|
//ffmpeg works with ours "fileops" helper
|
||||||
sprintf(url, "mpd://0x%8x", (unsigned int) &fopshelp);
|
if (av_open_input_file(&pFormatCtx, fopshelp.url, NULL, 0, NULL)!=0) {
|
||||||
|
|
||||||
if (av_open_input_file(&pFormatCtx, url, NULL, 0, NULL)!=0) {
|
|
||||||
ERROR("Open failed!\n");
|
ERROR("Open failed!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user