[FFmpeg-devel] [PATCH] libavcodec/v4l2_m2m_enc:free v4l2 encode session properly when initialiZzation fails Fix ticket 8285 bug
--- libavcodec/v4l2_m2m_enc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 474e6bef89..17fc3d30cf 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -312,6 +312,7 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) ret = ff_v4l2_m2m_codec_init(priv); if (ret) { av_log(avctx, AV_LOG_ERROR, "can't configure encoder\n"); +ff_v4l2_m2m_codec_end(priv); return ret; } s->avctx = avctx; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] lavfi/deshake: fix deshake crash issue.
1) The crash is caused by accessing un-allocated memory area. 2) You can't compute the contrast outside of search window (by default, rx=ry=16). From: ffmpeg-devel on behalf of Michael Niedermayer Sent: September 21, 2018 3:24 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] lavfi/deshake: fix deshake crash issue. On Thu, Sep 20, 2018 at 10:39:37AM +0800, myp...@gmail.com wrote: > On Wed, Sep 19, 2018 at 7:07 PM Michael Niedermayer > wrote: > > > > On Tue, Sep 18, 2018 at 09:37:29PM +0800, Jun Zhao wrote: > > > Fixes ticket #7441. > > > > > > Signed-off-by: Jun Zhao > > > --- > > > libavfilter/vf_deshake.c | 12 +++- > > > 1 files changed, 7 insertions(+), 5 deletions(-) > > > > this doesnt look correct > > > > the blocks that will be used are not going out of array? so the contrast > > calculated from them also should not > > > Do you mean the correct way is changing the pos calculated from: > pos = (y - i) * stride + (x - j); to pos = (y + i) * stride + (x + j) ? Iam not the author of vf_deshake, but whatever aligns the checked blocks correctly, should be the correct solution [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Modern terrorism, a quick summary: Need oil, start war with country that has oil, kill hundread thousand in war. Let country fall into chaos, be surprised about raise of fundamantalists. Drop more bombs, kill more people, be surprised about them taking revenge and drop even more bombs and strip your own citizens of their rights and freedoms. to be continued ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] libavformat/dashdec: Add a re-entrance check point after an interrupt operation
--- libavformat/dashdec.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 5730252..310dc20 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1764,6 +1764,12 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation if (pls->ctx) { close_demux_for_component(pls); } + +if (ff_check_interrupt(&s->interrupt_callback)) { +ret = AVERROR_EXIT; +goto fail; +} + if (!(pls->ctx = avformat_alloc_context())) { ret = AVERROR(ENOMEM); goto fail; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for un-free memory - bug # 7338
--- libavformat/dashdec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 09b06ef..5730252 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1879,7 +1879,6 @@ static int is_common_init_section_exist(struct representation **pls, int n_pls) static void copy_init_section(struct representation *rep_dest, struct representation *rep_src) { -*rep_dest->init_section = *rep_src->init_section; rep_dest->init_sec_buf = av_mallocz(rep_src->init_sec_buf_size); memcpy(rep_dest->init_sec_buf, rep_src->init_sec_buf, rep_src->init_sec_data_len); rep_dest->init_sec_buf_size = rep_src->init_sec_buf_size; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for Bug #7338
--- libavformat/dashdec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 09b06ef..fa784f1 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1040,7 +1040,6 @@ end: xmlFree(rep_bandwidth_val); if (rep_framerate_val) xmlFree(rep_framerate_val); - return ret; } @@ -1869,7 +1868,7 @@ static int is_common_init_section_exist(struct representation **pls, int n_pls) url = first_init_section->url; url_offset = first_init_section->url_offset; size = pls[0]->init_section->size; -for (i=0;iinit_section->url,url) || pls[i]->init_section->url_offset != url_offset || pls[i]->init_section->size != size) { return 0; } @@ -1879,7 +1878,6 @@ static int is_common_init_section_exist(struct representation **pls, int n_pls) static void copy_init_section(struct representation *rep_dest, struct representation *rep_src) { -*rep_dest->init_section = *rep_src->init_section; rep_dest->init_sec_buf = av_mallocz(rep_src->init_sec_buf_size); memcpy(rep_dest->init_sec_buf, rep_src->init_sec_buf, rep_src->init_sec_data_len); rep_dest->init_sec_buf_size = rep_src->init_sec_buf_size; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH]lavf/dashdec: Do not copy url on init copy
How about having different memory location for init_section of each presentation? rep_dest->init_section = (struct fragment *) av_mallocz(sizeof(struct fragment)); From: ffmpeg-devel on behalf of Carl Eugen Hoyos Sent: July 31, 2018 6:06 PM To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH]lavf/dashdec: Do not copy url on init copy Hi! Attached patch fixes ticket #7338, better fix welcome! Please comment, Carl Eugen ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] libavformat/dashdec: Fix for ticket 7149 (Segfault when decoding dash streams)
- Add NULL pointer check for init_section --- libavformat/dashdec.c | 30 +++--- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 42202e0..c6f350d 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1877,25 +1877,40 @@ fail: static int init_section_compare_video(DASHContext *c) { +char *url =NULL; +int64_t url_offset = -1; +int64_t size = -1; int i = 0; -char *url = c->videos[0]->init_section->url; -int64_t url_offset = c->videos[0]->init_section->url_offset; -int64_t size = c->videos[0]->init_section->size; + +if (c->videos[0]->init_section == NULL) +return 0; + +url = c->videos[0]->init_section->url; +url_offset = c->videos[0]->init_section->url_offset; +size = c->videos[0]->init_section->size; for (i=0;in_videos;i++) { if (av_strcasecmp(c->videos[i]->init_section->url,url) || c->videos[i]->init_section->url_offset != url_offset || c->videos[i]->init_section->size != size) { return 0; } } + return 1; } static int init_section_compare_audio(DASHContext *c) { +char *url =NULL; +int64_t url_offset = -1; +int64_t size = -1; int i = 0; -char *url = c->audios[0]->init_section->url; -int64_t url_offset = c->audios[0]->init_section->url_offset; -int64_t size = c->audios[0]->init_section->size; -for (i=0;in_audios;i++) { + +if (c->audios[0]->init_section == NULL) +return 0; + +url = c->audios[0]->init_section->url; +url_offset = c->audios[0]->init_section->url_offset; +size = c->audios[0]->init_section->size; +for (i=0; in_audios; i++) { if (av_strcasecmp(c->audios[i]->init_section->url,url) || c->audios[i]->init_section->url_offset != url_offset || c->audios[i]->init_section->size != size) { return 0; } @@ -1960,6 +1975,7 @@ static int dash_read_header(AVFormatContext *s) ++stream_index; } + if (c->n_audios) { c->is_init_section_common_audio = init_section_compare_audio(c); } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] libavformat/dashdec: Fix for ticket 7149 (Segfault when decoding dash streams)
- simplify the code to check common init section --- libavformat/dashdec.c | 48 +++- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index c6f350d..acaa1bf 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1875,43 +1875,22 @@ fail: return ret; } -static int init_section_compare_video(DASHContext *c) +static int is_common_init_section_exist(struct representation **pls, int n_pls) { +struct fragment *first_init_section = pls[0]->init_section; char *url =NULL; int64_t url_offset = -1; int64_t size = -1; int i = 0; -if (c->videos[0]->init_section == NULL) +if (first_init_section == NULL || n_pls == 0) return 0; -url = c->videos[0]->init_section->url; -url_offset = c->videos[0]->init_section->url_offset; -size = c->videos[0]->init_section->size; -for (i=0;in_videos;i++) { -if (av_strcasecmp(c->videos[i]->init_section->url,url) || c->videos[i]->init_section->url_offset != url_offset || c->videos[i]->init_section->size != size) { -return 0; -} -} - -return 1; -} - -static int init_section_compare_audio(DASHContext *c) -{ -char *url =NULL; -int64_t url_offset = -1; -int64_t size = -1; -int i = 0; - -if (c->audios[0]->init_section == NULL) -return 0; - -url = c->audios[0]->init_section->url; -url_offset = c->audios[0]->init_section->url_offset; -size = c->audios[0]->init_section->size; -for (i=0; in_audios; i++) { -if (av_strcasecmp(c->audios[i]->init_section->url,url) || c->audios[i]->init_section->url_offset != url_offset || c->audios[i]->init_section->size != size) { +url = first_init_section->url; +url_offset = first_init_section->url_offset; +size = pls[0]->init_section->size; +for (i=0;iinit_section->url,url) || pls[i]->init_section->url_offset != url_offset || pls[i]->init_section->size != size) { return 0; } } @@ -1957,9 +1936,7 @@ static int dash_read_header(AVFormatContext *s) s->duration = (int64_t) c->media_presentation_duration * AV_TIME_BASE; } -if (c->n_videos) { -c->is_init_section_common_video = init_section_compare_video(c); -} +c->is_init_section_common_video = is_common_init_section_exist(c->videos, c->n_videos); /* Open the demuxer for video and audio components if available */ for (i = 0; i < c->n_videos; i++) { @@ -1975,11 +1952,8 @@ static int dash_read_header(AVFormatContext *s) ++stream_index; } - -if (c->n_audios) { -c->is_init_section_common_audio = init_section_compare_audio(c); -} - + c->is_init_section_common_audio = is_common_init_section_exist(c->audios, c->n_audios); + for (i = 0; i < c->n_audios; i++) { struct representation *cur_audio = c->audios[i]; if (i > 0 && c->is_init_section_common_audio) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/3] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault)
Believe the comment is related to the 3rd patch. The update version is attached. From: 刘歧 Sent: January 16, 2018 10:39 PM To: FFmpeg development discussions and patches Cc: 刘歧; Colin NG Subject: Re: [FFmpeg-devel] [PATCH 2/3] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault) > On 17 Jan 2018, at 11:00, Colin NG wrote: > > - Add function 'resolve_content_path' to propagate the baseURL from upper > level nodes. > * if no baseURL is available, the path of mpd file will be set as the baseURL. > - Remove checking for newly established connection. > - Establish the communication protocol in each connection rather than > applying one protocol to all connection. > --- > libavformat/dashdec.c | 128 +- > 1 file changed, 115 insertions(+), 13 deletions(-) > > diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c > index 67a92d6..1d520d4 100644 > --- a/libavformat/dashdec.c > +++ b/libavformat/dashdec.c > @@ -149,6 +149,11 @@ typedef struct DASHContext { > AVDictionary *avio_opts; > } DASHContext; > > +static int ishttp(char *url) { > +const char *proto_name = avio_find_protocol_name(url); > +return av_strstart(proto_name, "http", NULL); > +} > + > static uint64_t get_current_time_in_sec(void) > { > return av_gettime() / 100; > @@ -420,7 +425,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, > const char *url, > else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) > return AVERROR_INVALIDDATA; > > -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); > +av_freep(pb); > +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); > if (ret >= 0) { > // update cookies on http response with setcookies. > char *new_cookies = NULL; > @@ -564,6 +570,7 @@ static struct fragment * get_Fragment(char *range) > seg->url_offset = strtoll(str_offset, NULL, 10); > seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset; > } > + > return seg; > } > > @@ -591,6 +598,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext > *s, struct representati > rep_id_val, > rep_bandwidth_val, > initialization_val); > + > if (!rep->init_section->url) { > av_free(rep->init_section); > xmlFree(initialization_val); > @@ -665,6 +673,105 @@ static int > parse_manifest_segmenttimeline(AVFormatContext *s, struct representat > return 0; > } > > +static int resolve_content_path(AVFormatContext *s, const char *url, > xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { > + > +char *tmp_str = NULL; > +char *path = NULL; > +char *mpdName = NULL; > +xmlNodePtr node = NULL; > +char *baseurl = NULL; > +char *root_url = NULL; > +char *text = NULL; > + > +int isRootHttp = 0; > +char token ='/'; > +int start = 0; > +int rootId = 0; > +int updated = 0; > +int size = 0; > +int i; > +int max_url_size = strlen(url); > + > +for (i = n_baseurl_nodes-1; i >= 0 ; i--) { > +text = xmlNodeGetContent(baseurl_nodes[i]); > +if (!text) > +continue; > +max_url_size += strlen(text); > +if (ishttp(text)) { > +xmlFree(text); > +break; > +} > +xmlFree(text); > +} > + > +text = av_mallocz(max_url_size); > +if (!text) { > +updated = AVERROR(ENOMEM); > +goto end; > +} > +av_strlcpy(text, url, strlen(url)+1); > +while (mpdName = av_strtok(text, "/", &text)) { > +size = strlen(mpdName); > +} > + > +path = av_mallocz(max_url_size); > +tmp_str = av_mallocz(max_url_size); > +if (!tmp_str || !path) { > +updated = AVERROR(ENOMEM); > +goto end; > +} > + > +av_strlcpy (path, url, strlen(url) - size + 1); > +for (rootId = n_baseurl_nodes - 1; rootId > 0; rootId --) { > +if (!(node = baseurl_nodes[rootId])) { > +continue; > +} > +if (ishttp(xmlNodeGetContent(node))) { > +break; > +} > +} > + > +node = baseurl_nodes[rootId]; > +baseurl = xmlNodeGetContent(node); > +root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path; > +if (node) { > +xmlNod
[FFmpeg-devel] [PATCH 3/3] libavformat/dashdec: Fix for ticket 6856 (filename limited to 1024)
--- libavformat/dashdec.c | 88 +-- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 1d520d4..9d5986d 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -147,6 +147,7 @@ typedef struct DASHContext { char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context char *allowed_extensions; AVDictionary *avio_opts; +int max_url_size; } DASHContext; static int ishttp(char *url) { @@ -154,6 +155,10 @@ static int ishttp(char *url) { return av_strstart(proto_name, "http", NULL); } +static int aligned(int val) { +return ((val + 0x3F) >> 6) << 6; +} + static uint64_t get_current_time_in_sec(void) { return av_gettime() / 100; @@ -452,6 +457,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, static char *get_content_url(xmlNodePtr *baseurl_nodes, int n_baseurl_nodes, + int max_url_size, char *rep_id_val, char *rep_bandwidth_val, char *val) @@ -459,43 +465,47 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, int i; char *text; char *url = NULL; -char tmp_str[MAX_URL_SIZE]; -char tmp_str_2[MAX_URL_SIZE]; - -memset(tmp_str, 0, sizeof(tmp_str)); +char *tmp_str = av_mallocz(max_url_size); +char *tmp_str_2 = av_mallocz(max_url_size); +if (!tmp_str || !tmp_str_2) { +return NULL; +} for (i = 0; i < n_baseurl_nodes; ++i) { if (baseurl_nodes[i] && baseurl_nodes[i]->children && baseurl_nodes[i]->children->type == XML_TEXT_NODE) { text = xmlNodeGetContent(baseurl_nodes[i]->children); if (text) { -memset(tmp_str, 0, sizeof(tmp_str)); -memset(tmp_str_2, 0, sizeof(tmp_str_2)); -ff_make_absolute_url(tmp_str_2, MAX_URL_SIZE, tmp_str, text); -av_strlcpy(tmp_str, tmp_str_2, sizeof(tmp_str)); +memset(tmp_str, 0, max_url_size); +memset(tmp_str_2, 0, max_url_size); +ff_make_absolute_url(tmp_str_2, max_url_size, tmp_str, text); +av_strlcpy(tmp_str, tmp_str_2, max_url_size); xmlFree(text); } } } if (val) -av_strlcat(tmp_str, (const char*)val, sizeof(tmp_str)); +av_strlcat(tmp_str, (const char*)val, max_url_size); if (rep_id_val) { url = av_strireplace(tmp_str, "$RepresentationID$", (const char*)rep_id_val); if (!url) { -return NULL; +goto end; } -av_strlcpy(tmp_str, url, sizeof(tmp_str)); +av_strlcpy(tmp_str, url, max_url_size); av_free(url); } if (rep_bandwidth_val && tmp_str[0] != '\0') { url = av_strireplace(tmp_str, "$Bandwidth$", (const char*)rep_bandwidth_val); if (!url) { -return NULL; +goto end; } } +end: +av_free(tmp_str); +av_free(tmp_str_2); return url; } @@ -580,9 +590,11 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati char *rep_id_val, char *rep_bandwidth_val) { +DASHContext *c = s->priv_data; char *initialization_val = NULL; char *media_val = NULL; char *range_val = NULL; +int max_url_size = c ? c->max_url_size: MAX_URL_SIZE; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); @@ -595,6 +607,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati return AVERROR(ENOMEM); } rep->init_section->url = get_content_url(baseurl_nodes, 4, + max_url_size, rep_id_val, rep_bandwidth_val, initialization_val); @@ -619,6 +632,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati return AVERROR(ENOMEM); } seg->url = get_content_url(baseurl_nodes, 4, + max_url_size, rep_id_val, rep_bandwidth_val, media_val); @@ -673,7 +687,7 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } -static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePt
[FFmpeg-devel] [PATCH 2/3] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault)
- Add function 'resolve_content_path' to propagate the baseURL from upper level nodes. * if no baseURL is available, the path of mpd file will be set as the baseURL. - Remove checking for newly established connection. - Establish the communication protocol in each connection rather than applying one protocol to all connection. --- libavformat/dashdec.c | 128 +- 1 file changed, 115 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 67a92d6..1d520d4 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -149,6 +149,11 @@ typedef struct DASHContext { AVDictionary *avio_opts; } DASHContext; +static int ishttp(char *url) { +const char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_current_time_in_sec(void) { return av_gettime() / 100; @@ -420,7 +425,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -564,6 +570,7 @@ static struct fragment * get_Fragment(char *range) seg->url_offset = strtoll(str_offset, NULL, 10); seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset; } + return seg; } @@ -591,6 +598,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati rep_id_val, rep_bandwidth_val, initialization_val); + if (!rep->init_section->url) { av_free(rep->init_section); xmlFree(initialization_val); @@ -665,6 +673,105 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +char *tmp_str = NULL; +char *path = NULL; +char *mpdName = NULL; +xmlNodePtr node = NULL; +char *baseurl = NULL; +char *root_url = NULL; +char *text = NULL; + +int isRootHttp = 0; +char token ='/'; +int start = 0; +int rootId = 0; +int updated = 0; +int size = 0; +int i; +int max_url_size = strlen(url); + +for (i = n_baseurl_nodes-1; i >= 0 ; i--) { +text = xmlNodeGetContent(baseurl_nodes[i]); +if (!text) +continue; +max_url_size += strlen(text); +if (ishttp(text)) { +xmlFree(text); +break; +} +xmlFree(text); +} + +text = av_mallocz(max_url_size); +if (!text) { +updated = AVERROR(ENOMEM); +goto end; +} +av_strlcpy(text, url, strlen(url)+1); +while (mpdName = av_strtok(text, "/", &text)) { +size = strlen(mpdName); +} + +path = av_mallocz(max_url_size); +tmp_str = av_mallocz(max_url_size); +if (!tmp_str || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy (path, url, strlen(url) - size + 1); +for (rootId = n_baseurl_nodes - 1; rootId > 0; rootId --) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +baseurl = xmlNodeGetContent(node); +root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path; +if (node) { +xmlNodeSetContent(node, root_url); +updated = 1; +} + +size = strlen(root_url); +isRootHttp = ishttp(root_url); + +if (root_url[size - 1] != token) { +av_strlcat(root_url, "/", size + 2); +size += 2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i == rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size + 1); +} +start = (text[0] == token); +av_strlcat(tmp_str, text + start, max_url_size); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +xmlFree(text); +} +} + +end: +av_free(path); +av_free(tmp_str); +return updated; + +} + static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node,
[FFmpeg-devel] [PATCH 1/3] libavformat/dashdec.c: Download dash content with byte range info
--- libavformat/dashdec.c | 36 ++-- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 2492f1d..67a92d6 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -550,6 +550,23 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * get_Fragment(char *range) +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +if (!seg) +return NULL; + +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset; +} +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -558,13 +575,16 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = get_Fragment(range_val); if (!rep->init_section) { xmlFree(initialization_val); +xmlFree(range_val); return AVERROR(ENOMEM); } rep->init_section->url = get_content_url(baseurl_nodes, 4, @@ -574,17 +594,20 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati if (!rep->init_section->url) { av_free(rep->init_section); xmlFree(initialization_val); +xmlFree(range_val); return AVERROR(ENOMEM); } -rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = get_Fragment(range_val); if (!seg) { xmlFree(media_val); +xmlFree(range_val); return AVERROR(ENOMEM); } seg->url = get_content_url(baseurl_nodes, 4, @@ -594,11 +617,12 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati if (!seg->url) { av_free(seg); xmlFree(media_val); +xmlFree(range_val); return AVERROR(ENOMEM); } -seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6856 (filename limited to 1024)
O. I forgot to include on other patches the ticket 6856 fix depended on. Colin PS: the depended patches are 0001-libavformat-dashdec-Fix-for-ticket-6658-Dash-demuxer.patch 0001-Download-dash-content-with-byte-range-info.patch (not necessary for compilation but needed for the complete solution) From: ffmpeg-devel on behalf of Michael Niedermayer Sent: January 13, 2018 6:56 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6856 (filename limited to 1024) On Fri, Jan 12, 2018 at 10:50:07PM +, Colin NG wrote: > --- > libavformat/dashdec.c | 87 > +-- > 1 file changed, 56 insertions(+), 31 deletions(-) applying: libavformat/dashdec: Fix for ticket 6856 (filename limited to 1024) error: sha1 information is lacking or useless (libavformat/dashdec.c). error: could not build fake ancestor Patch failed at 0001 libavformat/dashdec: Fix for ticket 6856 (filename limited to 1024) [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Asymptotically faster algorithms should always be preferred if you have asymptotical amounts of data From ab3436c0db92698b658aa4085a260f151e53fd81 Mon Sep 17 00:00:00 2001 From: Colin Ng Date: Wed, 3 Jan 2018 16:40:01 -0800 Subject: [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault) - Add function 'resolve_content_path' to propagate the baseURL from upper level nodes. * if no baseURL is available, the path of mpd file will be set as the baseURL. - Remove checking for newly established connection. - Establish the communication protocol in each connection rather than applying one protocol to all connection. --- libavformat/dashdec.c | 126 -- 1 file changed, 113 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..5345f91 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static int ishttp(char *url) { +const char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +645,103 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +char *tmp_str = NULL; +char *path = NULL; +char *mpdName = NULL; +xmlNodePtr node = NULL; +char *baseurl = NULL; +char *root_url = NULL; +char *text = NULL; + +int isRootHttp = 0; +char token ='/'; +int start = 0; +int rootId = 0; +int updated = 0; +int size = 0; +int i; +int max_url_size = strlen(url); + +for (i = n_baseurl_nodes-1; i >= 0 ; i--) { +text = xmlNodeGetContent(baseurl_nodes[i]); +if (!text) +continue; +max_url_size += strlen(text); +if (ishttp(text)) { +xmlFree(text); +break; +} +xmlFree(text); +} + +text = av_mallocz(max_url_size); +if (!text) { +updated = AVERROR(ENOMEM); +goto end; +} +av_strlcpy(text, url, strlen(url)+1); +while (mpdName = av_strtok(text, "/", &text)) { +size = strlen(mpdName); +} + +path = av_mallocz(max_url_size); +tmp_str = av_mallocz(max_url_size); +if (!tmp_str || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy (path, url, strlen(url) - size + 1); +for (rootId = n_baseurl_nodes - 1; rootId > 0; rootId --) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +baseurl = xmlNodeGetContent(node); +root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path; +if (node) { +xmlNodeSetContent(node, root_url); +} + +size = strlen(root_url); +isRootHttp = ishttp(root_url); + +if (root_url[size - 1] != token) { +av_strlcat(root_
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6856 (filename limited to 1024)
--- libavformat/dashdec.c | 87 +-- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 5345f91..7316213 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -141,6 +141,7 @@ typedef struct DASHContext { char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context char *allowed_extensions; AVDictionary *avio_opts; +int max_url_size; } DASHContext; static uint64_t get_current_time_in_sec(void) @@ -153,6 +154,10 @@ static int ishttp(char *url) { return av_strstart(proto_name, "http", NULL); } +static int aligned(int val) { +return ((val + 0x3F) >> 6) << 6; +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -424,6 +429,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, static char *get_content_url(xmlNodePtr *baseurl_nodes, int n_baseurl_nodes, + int max_url_size, char *rep_id_val, char *rep_bandwidth_val, char *val) @@ -431,10 +437,13 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, int i; char *text; char *url = NULL; -char tmp_str[MAX_URL_SIZE]; -char tmp_str_2[MAX_URL_SIZE]; -memset(tmp_str, 0, sizeof(tmp_str)); +char *tmp_str = av_mallocz(max_url_size); +char *tmp_str_2 = av_mallocz(max_url_size); + +if (!tmp_str || !tmp_str_2) { +return NULL; +} for (i = 0; i < n_baseurl_nodes; ++i) { if (baseurl_nodes[i] && @@ -442,32 +451,35 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, baseurl_nodes[i]->children->type == XML_TEXT_NODE) { text = xmlNodeGetContent(baseurl_nodes[i]->children); if (text) { -memset(tmp_str, 0, sizeof(tmp_str)); -memset(tmp_str_2, 0, sizeof(tmp_str_2)); -ff_make_absolute_url(tmp_str_2, MAX_URL_SIZE, tmp_str, text); -av_strlcpy(tmp_str, tmp_str_2, sizeof(tmp_str)); +memset(tmp_str, 0, max_url_size); +memset(tmp_str_2, 0, max_url_size); +ff_make_absolute_url(tmp_str_2, max_url_size, tmp_str, text); +av_strlcpy(tmp_str, tmp_str_2, max_url_size); xmlFree(text); } } } if (val) -av_strlcat(tmp_str, (const char*)val, sizeof(tmp_str)); - +av_strlcat(tmp_str, (const char*)val, max_url_size); if (rep_id_val) { url = av_strireplace(tmp_str, "$RepresentationID$", (const char*)rep_id_val); if (!url) { -return NULL; +goto end; } -av_strlcpy(tmp_str, url, sizeof(tmp_str)); +av_strlcpy(tmp_str, url, max_url_size); av_free(url); } if (rep_bandwidth_val && tmp_str[0] != '\0') { url = av_strireplace(tmp_str, "$Bandwidth$", (const char*)rep_bandwidth_val); if (!url) { -return NULL; + goto end; } } + +end: +av_free(tmp_str); +av_free(tmp_str_2); return url; } @@ -540,7 +552,7 @@ static struct fragment * get_Fragment(char *range) char *str_end_offset; char *str_offset = av_strtok(range, "-", &str_end_offset); seg->url_offset = strtoll(str_offset, NULL, 10); -seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset; +seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset; } return seg; @@ -552,9 +564,11 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati char *rep_id_val, char *rep_bandwidth_val) { +DASHContext *c = s->priv_data; char *initialization_val = NULL; char *media_val = NULL; char *range_val = NULL; +int max_url_size = c ? c->max_url_size: MAX_URL_SIZE; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); @@ -567,6 +581,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati return AVERROR(ENOMEM); } rep->init_section->url = get_content_url(baseurl_nodes, 4, + max_url_size, rep_id_val, rep_bandwidth_val, initialization_val); @@ -591,6 +606,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati return AVERROR(ENOMEM);
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault)
- Add function 'resolve_content_path' to propagate the baseURL from upper level nodes. * if no baseURL is available, the path of mpd file will be set as the baseURL. - Remove checking for newly established connection. - Establish the communication protocol in each connection rather than applying one protocol to all connection. --- libavformat/dashdec.c | 126 -- 1 file changed, 113 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..5345f91 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static int ishttp(char *url) { +const char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +645,103 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +char *tmp_str = NULL; +char *path = NULL; +char *mpdName = NULL; +xmlNodePtr node = NULL; +char *baseurl = NULL; +char *root_url = NULL; +char *text = NULL; + +int isRootHttp = 0; +char token ='/'; +int start = 0; +int rootId = 0; +int updated = 0; +int size = 0; +int i; +int max_url_size = strlen(url); + +for (i = n_baseurl_nodes-1; i >= 0 ; i--) { +text = xmlNodeGetContent(baseurl_nodes[i]); +if (!text) +continue; +max_url_size += strlen(text); +if (ishttp(text)) { +xmlFree(text); +break; +} +xmlFree(text); +} + +text = av_mallocz(max_url_size); +if (!text) { +updated = AVERROR(ENOMEM); +goto end; +} +av_strlcpy(text, url, strlen(url)+1); +while (mpdName = av_strtok(text, "/", &text)) { +size = strlen(mpdName); +} + +path = av_mallocz(max_url_size); +tmp_str = av_mallocz(max_url_size); +if (!tmp_str || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy (path, url, strlen(url) - size + 1); +for (rootId = n_baseurl_nodes - 1; rootId > 0; rootId --) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +baseurl = xmlNodeGetContent(node); +root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path; +if (node) { +xmlNodeSetContent(node, root_url); +} + +size = strlen(root_url); +isRootHttp = ishttp(root_url); + +if (root_url[size - 1] != token) { +av_strlcat(root_url, "/", size + 2); +size += 2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i == rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size + 1); +} +start = (text[0] == token); +av_strlcat(tmp_str, text + start, max_url_size); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +xmlFree(text); +} +} + +end: +av_free(path); +av_free(tmp_str); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +801,11 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +ret = resolve_content_path(s, url, baseurl_nodes, 4); +if (ret == AVERROR(ENOMEM) || ret == 0) { +goto end; +} + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1101,9 @@ static int parse_manifest(AVFormatContext *s, const ch
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault)
- Add function 'resolve_content_path' to propagate the baseURL from upper level nodes. * if no baseURL is available, the path of mpd file will be set as the baseURL. - Remove checking for newly established connection. - Establish the communication protocol in each connection rather than applying one protocol to all connection. --- libavformat/dashdec.c | 107 -- 1 file changed, 94 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..e41ba96 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static int ishttp(char *url) { +const char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +645,84 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +char *tmp_str = av_mallocz(MAX_URL_SIZE); +char *path = av_mallocz(MAX_URL_SIZE); +char *mpdName = NULL; +xmlNodePtr node = NULL; +char *baseurl = NULL; +char *root_url = NULL; +char *text = NULL; + +int isRootHttp = 0; +char token ='/'; +int start = 0; +int rootId = 0; +int updated = 0; +int size = 0; +int i; + +if (!tmp_str || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy(tmp_str, url, strlen(url) + 1); +mpdName = strtok (tmp_str, "/"); +while (mpdName = strtok (NULL, "/")) { +size = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url) - size + 1); +for (rootId = n_baseurl_nodes - 1; rootId > 0; rootId --) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +baseurl = xmlNodeGetContent(node); +root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path; +if (node) { +xmlNodeSetContent(node, root_url); +} + +size = strlen(root_url); +isRootHttp = ishttp(root_url); + +if (root_url[size - 1] == token) { +av_strlcat(root_url, "/", size + 2); +size += 2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i == rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size + 1); +} +start = (text[0] == token); +av_strlcat(tmp_str, text + start, MAX_URL_SIZE); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +xmlFree(text); +} +} + +end: +av_free(path); +av_free(tmp_str); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +782,11 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +ret = resolve_content_path(s, url, baseurl_nodes, 4); +if (ret == AVERROR(ENOMEM) || ret == 0) { +goto end; +} + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1082,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); +if (!mpd_baseurl_node) { +mpd_baseurl_node = xmlNewNode(NULL, "BaseURL"); +} // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); @@ -1315,6 +1407,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, } else { ret = av
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault) - Add function 'resolve_content_path' to propagate the baseURL from upper level nodes. * if no baseURL is availa
--- libavformat/dashdec.c | 110 -- 1 file changed, 97 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..6574e56 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static int ishttp(char *url) { +const char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +646,85 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +char *tmp_str = av_mallocz(MAX_URL_SIZE); +char *path = av_mallocz(MAX_URL_SIZE); +char *mpdName = NULL; +xmlNodePtr node = NULL; +char *baseurl = NULL; +char *root_url = NULL; +char *text = NULL; + +int isRootHttp = 0; +char token ='/'; +int start = 0; +int rootId = 0; +int updated = 0; +int size = 0; +int i; + +if (!tmp_str || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy(tmp_str, url, strlen(url) + 1); +mpdName = strtok (tmp_str, "/"); +while (mpdName = strtok (NULL, "/")) { +size = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url) - size + 1); + +for (rootId = n_baseurl_nodes - 1; rootId > 0; rootId--) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +baseurl = xmlNodeGetContent(node); +root_url = (av_strcasecmp(baseurl, ""))? baseurl: path; +if (node) { +xmlNodeSetContent(node, root_url); +} + +size = strlen(root_url); +isRootHttp= ishttp(root_url); + +if (root_url[size-1]==token) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i == rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size + 1); +} +start = (text[0] == token) ? 1: 0; +av_strlcat(tmp_str, text + start, MAX_URL_SIZE); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +xmlFree(text); +} +} + +end: +av_free(path); +av_free(tmp_str); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +784,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +ret = resolve_content_path(s, url, baseurl_nodes, 4); +if (ret == AVERROR(ENOMEM) || ret == 0) { +goto end; +} + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1085,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); +if (!mpd_baseurl_node) { +mpd_baseurl_node = xmlNewNode(NULL, "BaseURL"); +} // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); @@ -1315,6 +1410,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, } else { ret = avio_read(pls->input, buf, buf_size); } if (ret > 0) pls->cur_seg_offset += ret; @@ -1343,18 +1439,6 @@ static int open_input(DASHContext *c, struct representation *pls, struct fragmen goto cleanup; } -/* Seek to the requested position. If this was a HTTP request, the offset - * should alre
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault) - Add function 'resolve_content_path' to propagate the baseURL from upper level nodes. * if no baseURL is availa
--- libavformat/dashdec.c | 116 -- 1 file changed, 103 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..cdb9f67 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static int ishttp(char *url) { +const char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +646,91 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +char *tmp_str = av_mallocz(MAX_URL_SIZE); +char *tmp_str_2= av_mallocz(MAX_URL_SIZE); +char *path = av_mallocz(MAX_URL_SIZE); +char *mpdName = NULL; +xmlNodePtr node = NULL; +char *baseurl = NULL; +char *root_url = NULL; +char *text = NULL; + +int isRootHttp = 0; +char token ='/'; +int start = 0; +int rootId = 0; +int updated = 0; +int size = 0; +int i; + +if (!tmp_str || !tmp_str_2 || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy(tmp_str, url, strlen(url)+1); +mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/"))) { +size = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url)-size+1); + +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +baseurl = xmlNodeGetContent(node); +root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +size = strlen(root_url); +isRootHttp= ishttp(root_url); + +if (root_url[size-1]==token) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i==rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); + +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size+1); +} +start = (text[0]==token) ? 1: 0; +memset(tmp_str_2, 0, strlen(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +xmlFree(text); +} +} + +end: +av_free(path); +av_free(tmp_str); +av_free(tmp_str_2); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +790,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +ret = resolve_content_path(s, url, baseurl_nodes, 4); + +if (ret == AVERROR(ENOMEM) || ret == 0) { +goto end; +} + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1091,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); +if (!mpd_baseurl_node) { +mpd_baseurl_node = xmlNewNode(NULL, "BaseURL"); +} // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); @@ -1315,6 +1416,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, } else { ret = avio_read(pls->input, buf, buf_size); } + if (ret > 0) pls->cur_seg_offset += ret; @@ -1343,18 +1445,6 @@ static int open_input(DASHContext *c, struct representation *pls, stru
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault) - Add function 'resolve_content_path' to propagate the baseURL from upper level nodes. * if no baseURL is availa
--- libavformat/dashdec.c | 111 -- 1 file changed, 98 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..6e35e91 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static char * ishttp(char *url) { +char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +646,86 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +int i; +char *text; +char *tmp_str = av_mallocz(MAX_URL_SIZE); +char *tmp_str_2= av_mallocz(MAX_URL_SIZE); + +char *path = av_mallocz(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +if (!tmp_str || !tmp_str_2 || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/"))) { +nameSize = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url)-nameSize+1); + +int rootId = 0; +xmlNodePtr *node = NULL; +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +int size = strlen(root_url); +char *isRootHttp = ishttp(root_url); + +char token ='/'; +if (root_url[size] == token) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i == rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); + +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size+1); +} +int start = (text[0]==token) ? 1: 0; +memset(tmp_str_2, 0, strlen(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlFree(text); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +} +} + +end: +av_free(path); +av_free(tmp_str); +av_free(tmp_str_2); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +785,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +ret = resolve_content_path(s, url, baseurl_nodes, 4); + +if (ret == AVERROR(ENOMEM) || ret == 0) { +goto end; +} + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1086,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); +if (!mpd_baseurl_node) { +mpd_baseurl_node = xmlNewNode(node, "BaseURL"); +} // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); @@ -1315,6 +1411,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, } else { ret = avio_read(pls->input, buf, buf_size); } + if (ret > 0) pls->cur_seg_offset += ret; @@ -1343,18 +1440,6 @@ static int open_input(DASHContext *c, struct representation *pls, struct fragmen goto cleanup; } -/* Seek to the requested position. If this
Re: [FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault)
From: ffmpeg-devel on behalf of Steven Liu Sent: December 4, 2017 4:52 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault) 2017-12-04 12:28 GMT+08:00 Colin NG : > --- > libavformat/dashdec.c | 112 > -- > 1 file changed, 99 insertions(+), 13 deletions(-) > > diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c > index 3798649..d04bec0 100644 > --- a/libavformat/dashdec.c > +++ b/libavformat/dashdec.c > @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) > return av_gettime() / 100; > } > > +static char * ishttp(char *url) { > +char *proto_name = avio_find_protocol_name(url); > +return av_strstart(proto_name, "http", NULL); > +} > + > static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char > *datetime) > { > struct tm timeinfo; > @@ -392,7 +397,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, > const char *url, > else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) > return AVERROR_INVALIDDATA; > > -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); > +av_freep(pb); > +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); > + > if (ret >= 0) { > // update cookies on http response with setcookies. > char *new_cookies = NULL; > @@ -639,6 +646,87 @@ static int > parse_manifest_segmenttimeline(AVFormatContext *s, struct representat > return 0; > } > > +static int resolve_content_path(AVFormatContext *s, const char *url, > xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { > + > +int i; > +char *text; > +char *tmp_str = av_mallocz(MAX_URL_SIZE); > +char *tmp_str_2= av_mallocz(MAX_URL_SIZE); > + > +char *path = av_mallocz(MAX_URL_SIZE); > +int nameSize = 0; > +int updated = 0; > + > +if (!tmp_str || !tmp_str_2 || !path) { > +updated = AVERROR(ENOMEM); > +goto end; > +} > + > +av_strlcpy(tmp_str, url, strlen(url)+1); > +char *mpdName = strtok (tmp_str," /"); > + > +while ((mpdName =strtok (NULL, "/"))) { What dose this do? The above instruction will split the url (i.e. url of the mpd file) elements with "/" separator in between. > +nameSize = strlen(mpdName); > +} > + > +av_strlcpy (path, url, strlen(url)-nameSize+1); > + > +int rootId = 0; > +xmlNodePtr *node = NULL; > +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) { > +if (!(node = baseurl_nodes[rootId])) { > +continue; > +} > +if (ishttp(xmlNodeGetContent(node))) { > +break; > +} > +} > + > +node = baseurl_nodes[rootId]; > +char *baseurl = xmlNodeGetContent(node); > +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; > + > +if (node) { > +xmlNodeSetContent(node, root_url); > +} > + > +int size = strlen(root_url); > +char *isRootHttp= ishttp(root_url); > + > +char token ='/'; > +//if (root_url[size-1]==token) { > +if (av_strncasecmp(&root_url[size-1],&token, 1) != 0) { If this only compare 1 char, why don't use root_url[size-1] == token ? > +av_strlcat(root_url, "/", size+2); > +size+=2; > +} > + > +for (i = 0; i < n_baseurl_nodes; ++i) { > +if (i==rootId) { > +continue; > +} > +text = xmlNodeGetContent(baseurl_nodes[i]); > +if (text) { > +memset(tmp_str, 0, strlen(tmp_str)); > + > +if (!ishttp(text) && isRootHttp) { > +av_strlcpy(tmp_str, root_url, size+1); > +} > +int start = (text[0]==token) ? 1: 0; > +memset(tmp_str_2, 0, strlen(tmp_str_2)); > +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); > +xmlFree(text); > +xmlNodeSetContent(baseurl_nodes[i], tmp_str); > +updated = 1; > +} > +} > + > +end: > +av_free(path); > +av_free(tmp_str); > +av_free(tmp_str_2); > +return updated; > + > +} > static int parse_manifest_representation(AVFormatContext *s, const char *url, > xmlNodePtr node, > xmlNodePtr adaptionset_node, > @@ -698,6 +786,12 @@ static int parse_manifest_r
[FFmpeg-devel] [PATCH] libavformat/dashdec: Fix for ticket 6658 (Dash demuxer segfault)
--- libavformat/dashdec.c | 112 -- 1 file changed, 99 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..d04bec0 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static char * ishttp(char *url) { +char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +646,87 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +int i; +char *text; +char *tmp_str = av_mallocz(MAX_URL_SIZE); +char *tmp_str_2= av_mallocz(MAX_URL_SIZE); + +char *path = av_mallocz(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +if (!tmp_str || !tmp_str_2 || !path) { +updated = AVERROR(ENOMEM); +goto end; +} + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/"))) { +nameSize = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url)-nameSize+1); + +int rootId = 0; +xmlNodePtr *node = NULL; +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +int size = strlen(root_url); +char *isRootHttp= ishttp(root_url); + +char token ='/'; +//if (root_url[size-1]==token) { +if (av_strncasecmp(&root_url[size-1],&token, 1) != 0) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i==rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); + +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size+1); +} +int start = (text[0]==token) ? 1: 0; +memset(tmp_str_2, 0, strlen(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlFree(text); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +} +} + +end: +av_free(path); +av_free(tmp_str); +av_free(tmp_str_2); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +786,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +ret = resolve_content_path(s, url, baseurl_nodes, 4); + +if (ret == AVERROR(ENOMEM)) { +goto end; +} + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1087,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); +if (!mpd_baseurl_node) { +mpd_baseurl_node = xmlNewNode(node, "BaseURL"); +} // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); @@ -1315,6 +1412,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, } else { ret = avio_read(pls->input, buf, buf_size); } + if (ret > 0) pls->cur_seg_offset += ret; @@ -1343,18 +1441,6 @@ static int open_input(DASHContext *c, struct representation *pls, struct fragmen goto cleanup; }
[FFmpeg-devel] [PATCH] libavcodec/dvbsubdec: Fix for ticket 6796 (ffprobe show_frames ts dvbsubs infinite loop)
--- libavcodec/dvbsubdec.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index a657b1d..29997a2 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -1596,7 +1596,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, } static int dvbsub_decode(AVCodecContext *avctx, - void *data, int *data_size, + void *data, int *got_output, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -1654,7 +1654,7 @@ static int dvbsub_decode(AVCodecContext *avctx, int ret = 0; switch (segment_type) { case DVBSUB_PAGE_SEGMENT: -ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size); +ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, got_output); got_segment |= 1; break; case DVBSUB_REGION_SEGMENT: @@ -1676,7 +1676,7 @@ static int dvbsub_decode(AVCodecContext *avctx, got_dds = 1; break; case DVBSUB_DISPLAY_SEGMENT: -ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size); +ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, got_output); if (got_segment == 15 && !got_dds && !avctx->width && !avctx->height) { // Default from ETSI EN 300 743 V1.3.1 (7.2.1) avctx->width = 720; @@ -1699,12 +1699,12 @@ static int dvbsub_decode(AVCodecContext *avctx, // segments then we need no further data. if (got_segment == 15) { av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n"); -dvbsub_display_end_segment(avctx, p, 0, sub, data_size); +dvbsub_display_end_segment(avctx, p, 0, sub, got_output); } end: if(ret < 0) { -*data_size = 0; +*got_output = 0; avsubtitle_free(sub); return ret; } else { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] fftools/ffprobe: Fix for ticket 6796 (ffprobe show_frames ts dvbsubs infinite loop)
--- fftools/ffprobe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 0e7a771..6ddd81e 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2280,6 +2280,7 @@ static av_always_inline int process_frame(WriterContext *w, break; default: *packet_new = 0; +break; } } else { *packet_new = 0; @@ -2290,6 +2291,7 @@ static av_always_inline int process_frame(WriterContext *w, if (got_frame) { int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE); nb_streams_frames[pkt->stream_index]++; +got_frame = (par->codec_type == AVMEDIA_TYPE_SUBTITLE) ? 0: got_frame; if (do_show_frames) if (is_sub) show_subtitle(w, &sub, ifile->streams[pkt->stream_index].st, fmt_ctx); -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] Fix for ticket 6796 (ffprobe show_frames ts dvbsubs infinate loop)
--- fftools/ffprobe.c | 2 ++ libavcodec/dvbsubdec.c | 10 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 0e7a771..6ddd81e 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2280,6 +2280,7 @@ static av_always_inline int process_frame(WriterContext *w, break; default: *packet_new = 0; +break; } } else { *packet_new = 0; @@ -2290,6 +2291,7 @@ static av_always_inline int process_frame(WriterContext *w, if (got_frame) { int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE); nb_streams_frames[pkt->stream_index]++; +got_frame = (par->codec_type == AVMEDIA_TYPE_SUBTITLE) ? 0: got_frame; if (do_show_frames) if (is_sub) show_subtitle(w, &sub, ifile->streams[pkt->stream_index].st, fmt_ctx); diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index a657b1d..29997a2 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -1596,7 +1596,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, } static int dvbsub_decode(AVCodecContext *avctx, - void *data, int *data_size, + void *data, int *got_output, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -1654,7 +1654,7 @@ static int dvbsub_decode(AVCodecContext *avctx, int ret = 0; switch (segment_type) { case DVBSUB_PAGE_SEGMENT: -ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size); +ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, got_output); got_segment |= 1; break; case DVBSUB_REGION_SEGMENT: @@ -1676,7 +1676,7 @@ static int dvbsub_decode(AVCodecContext *avctx, got_dds = 1; break; case DVBSUB_DISPLAY_SEGMENT: -ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size); +ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, got_output); if (got_segment == 15 && !got_dds && !avctx->width && !avctx->height) { // Default from ETSI EN 300 743 V1.3.1 (7.2.1) avctx->width = 720; @@ -1699,12 +1699,12 @@ static int dvbsub_decode(AVCodecContext *avctx, // segments then we need no further data. if (got_segment == 15) { av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n"); -dvbsub_display_end_segment(avctx, p, 0, sub, data_size); +dvbsub_display_end_segment(avctx, p, 0, sub, got_output); } end: if(ret < 0) { -*data_size = 0; +*got_output = 0; avsubtitle_free(sub); return ret; } else { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] Fix for ticket 6796 (ffprobe show_frames ts dvbsubs infinate loop)
--- fftools/ffprobe.c | 5 + libavcodec/decode.c | 5 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 0e7a771..20b64ef 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2276,10 +2276,14 @@ static av_always_inline int process_frame(WriterContext *w, case AVMEDIA_TYPE_SUBTITLE: ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt); +if (ret == AVERROR(EINVAL) || ret == AVERROR_INVALIDDATA) { +ret = 0; +} *packet_new = 0; break; default: *packet_new = 0; +break; } } else { *packet_new = 0; @@ -2290,6 +2294,7 @@ static av_always_inline int process_frame(WriterContext *w, if (got_frame) { int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE); nb_streams_frames[pkt->stream_index]++; +got_frame = 0; if (do_show_frames) if (is_sub) show_subtitle(w, &sub, ifile->streams[pkt->stream_index].st, fmt_ctx); diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 3f5b086..d6cc671 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1024,7 +1024,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) sub->pts = av_rescale_q(avpkt->pts, avctx->pkt_timebase, AV_TIME_BASE_Q); -ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded); +ret = avctx->codec->decode(avctx, sub, &pkt_recoded.size, &pkt_recoded); +if (ret == avpkt->size) { + *got_sub_ptr = 1; +} av_assert1((ret >= 0) >= !!*got_sub_ptr && !!*got_sub_ptr >= !!sub->num_rects); -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] Fix for ticket 6658 (Dash demuxer segfault)
--- libavformat/dashdec.c | 95 --- 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..5d5970e 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static char * ishttp(char *url) { +char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +646,74 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +int i; +char *text; +char tmp_str[MAX_URL_SIZE]; +char tmp_str_2[MAX_URL_SIZE]; + +char *path = av_mallocz(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/"))) { +nameSize = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url)-nameSize+1); + +int rootId = 0; +xmlNodePtr *node = NULL; +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) { +if (!(node = baseurl_nodes[rootId])) continue; +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +int size = strlen(root_url); +char *isRootHttp= ishttp(root_url); + +char token ='/'; +if (av_strncasecmp(&root_url[size-1],&token, 1) != 0) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i==rootId) continue; +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); + +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size+1); +} +int start = (av_strncasecmp(text, &token, 1) == 0) ? 1: 0; +memset(tmp_str_2, 0, strlen(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlFree(text); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +} +} + +av_free(path); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +773,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +resolve_content_path(s, url, baseurl_nodes, 4); + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1070,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); +if (!mpd_baseurl_node) { +mpd_baseurl_node = xmlNewNode(node, "BaseURL"); +} // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); @@ -1315,6 +1395,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, } else { ret = avio_read(pls->input, buf, buf_size); } + if (ret > 0) pls->cur_seg_offset += ret; @@ -1343,18 +1424,6 @@ static int open_input(DASHContext *c, struct representation *pls, struct fragmen goto cleanup; } -/* Seek to the requested position. If this was a HTTP request, the offset - * should already be where want it to, but this allows e.g. local testing - * without a HTTP server. */ -if (!ret && seg->url_offset) { -int64_t seekret = avio_seek(pls->input, seg->url_offset, SEEK_SET); -if (seekret < 0) { -
Re: [FFmpeg-devel] [PATCH] libavcodec/opus: Add NULL pointer check for incoming data; avoid segfault
It still crashes with the following change. It crashes at ff_pvq_search_exact_avx () instead. We should wait for your improvement to fix the crash. Colin From: ffmpeg-devel on behalf of Rostislav Pehlivanov Sent: November 22, 2017 8:02 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] libavcodec/opus: Add NULL pointer check for incoming data; avoid segfault On 23 November 2017 at 00:53, Colin NG wrote: > --- > Fix for ticket 7674 > > libavcodec/opus_pvq.c | 16 +--- > 1 file changed, 13 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c > index f98b85d..02ccd69 100644 > --- a/libavcodec/opus_pvq.c > +++ b/libavcodec/opus_pvq.c > @@ -504,6 +504,9 @@ static av_always_inline uint32_t > quant_band_template(CeltPVQ *pvq, CeltFrame *f, > int longblocks = (B0 == 1); > uint32_t cm = 0; > > + if (!X) > +return cm; > + > if (N == 1) { > float *x = X; > for (i = 0; i <= stereo; i++) { > @@ -795,7 +798,7 @@ static av_always_inline uint32_t > quant_band_template(CeltPVQ *pvq, CeltFrame *f, > f->remaining2 -= curr_bits; > } > > -if (q != 0) { > +if (X && !q) { > /* Finally do the actual (de)quantization */ > if (quant) { > cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) > << ((q >> 3) - 1), > @@ -902,6 +905,9 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, > OpusRangeCoder *rc, int b > float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << > f->size); > OPUS_RC_CHECKPOINT_SPAWN(rc); > > +if (!X && !Y) > +return 0.0f; > + > memcpy(X, X_orig, band_size*sizeof(float)); > if (Y) > memcpy(Y, Y_orig, band_size*sizeof(float)); > @@ -911,7 +917,6 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, > OpusRangeCoder *rc, int b > int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band); > b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] + > curr_balance), 14); > } > - > if (f->dual_stereo) { > pvq->encode_band(pvq, f, rc, band, X, NULL, band_size, b / 2, > f->blocks, NULL, > f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]); > @@ -925,7 +930,12 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame > *f, OpusRangeCoder *rc, int b > > for (i = 0; i < band_size; i++) { > err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]); > -err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]); > +} > + > + if (Y) { > +for (i = 0; i < band_size; i++) { > +err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]); > +} > } > > dist = sqrtf(err_x) + sqrtf(err_y); > -- > 2.7.4 > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ffmpeg-devel Info Page<http://ffmpeg.org/mailman/listinfo/ffmpeg-devel> ffmpeg.org This list is about FFmpeg development discussions and patches; but not for bug-reports. Please read the Code-of-conduct. To see the collection of prior postings to ... > I actually found out about this bug while working on it a few days ago but wanted to wait until I got the opus_rc and some opusenc_psy improvements fully done. Pushed my fix for mono. I disagree with the rest. There should always be a channel of audio (X) to analyze. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ffmpeg-devel Info Page<http://ffmpeg.org/mailman/listinfo/ffmpeg-devel> ffmpeg.org This list is about FFmpeg development discussions and patches; but not for bug-reports. Please read the Code-of-conduct. To see the collection of prior postings to ... ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault)
Clean up coding style. diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 3798649..7e7ae52 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static char *ishttp(char *url) { +char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -639,6 +645,78 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) + { +int i; +char *text; +char tmp_str[MAX_URL_SIZE]; +char tmp_str_2[MAX_URL_SIZE]; + +char *path = av_mallocz(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok(tmp_str, "/"); + +while ((mpdName = strtok(NULL, "/"))) { +nameSize = strlen(mpdName); +} + +av_strlcpy(path, url, strlen(url)-nameSize+1); + +int rootId = 0; +xmlNodePtr *node = NULL; +for (rootId = n_baseurl_nodes-1; rootId > 0; rootId--) { +if (!(node = baseurl_nodes[rootId])) { +continue; +} +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +int size = strlen(root_url); +char *isRootHttp = ishttp(root_url); + +char token = '/'; +if (strncmp(&root_url[size-1], &token, 1) != 0) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; i++) { +if (i == rootId) { +continue; +} +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); + +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size+1); +} +int start = (strncmp(text, &token, 1) == 0) ? 1: 0; +memset(tmp_str_2, 0, strlen(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlFree(text); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +} +} + +av_free(path); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -698,6 +776,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +resolve_content_path(s, url, baseurl_nodes, 4); + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -993,6 +1073,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); +if (!mpd_baseurl_node) { +mpd_baseurl_node = xmlNewNode(node, "BaseURL"); +} // at now we can handle only one period, with the longest duration node = xmlFirstElementChild(node); ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] libavcodec/opus: Add NULL pointer check for incoming data; avoid segfault
--- Fix for ticket 7674 libavcodec/opus_pvq.c | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c index f98b85d..02ccd69 100644 --- a/libavcodec/opus_pvq.c +++ b/libavcodec/opus_pvq.c @@ -504,6 +504,9 @@ static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f, int longblocks = (B0 == 1); uint32_t cm = 0; + if (!X) +return cm; + if (N == 1) { float *x = X; for (i = 0; i <= stereo; i++) { @@ -795,7 +798,7 @@ static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f, f->remaining2 -= curr_bits; } -if (q != 0) { +if (X && !q) { /* Finally do the actual (de)quantization */ if (quant) { cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), @@ -902,6 +905,9 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size); OPUS_RC_CHECKPOINT_SPAWN(rc); +if (!X && !Y) +return 0.0f; + memcpy(X, X_orig, band_size*sizeof(float)); if (Y) memcpy(Y, Y_orig, band_size*sizeof(float)); @@ -911,7 +917,6 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band); b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] + curr_balance), 14); } - if (f->dual_stereo) { pvq->encode_band(pvq, f, rc, band, X, NULL, band_size, b / 2, f->blocks, NULL, f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]); @@ -925,7 +930,12 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b for (i = 0; i < band_size; i++) { err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]); -err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]); +} + + if (Y) { +for (i = 0; i < band_size; i++) { +err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]); +} } dist = sqrtf(err_x) + sqrtf(err_y); -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] Fix for ticket #6764
Add NULL pointer check for incoming audio data. diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c index f98b85d..f1dbc5d 100644 --- a/libavcodec/opus_pvq.c +++ b/libavcodec/opus_pvq.c @@ -504,6 +504,9 @@ static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f, int longblocks = (B0 == 1); uint32_t cm = 0; + if (!X) +return cm; + if (N == 1) { float *x = X; for (i = 0; i <= stereo; i++) { @@ -795,7 +798,7 @@ static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f, f->remaining2 -= curr_bits; } -if (q != 0) { +if (X && q != 0) { /* Finally do the actual (de)quantization */ if (quant) { cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), @@ -902,6 +905,9 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size); OPUS_RC_CHECKPOINT_SPAWN(rc); +if (!X && !Y) +return 0.0f; + memcpy(X, X_orig, band_size*sizeof(float)); if (Y) memcpy(Y, Y_orig, band_size*sizeof(float)); @@ -911,7 +917,6 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band); b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] + curr_balance), 14); } - if (f->dual_stereo) { pvq->encode_band(pvq, f, rc, band, X, NULL, band_size, b / 2, f->blocks, NULL, f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]); @@ -925,7 +930,12 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b for (i = 0; i < band_size; i++) { err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]); -err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]); +} + + if (Y) { +for (i = 0; i < band_size; i++) { +err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]); +} } dist = sqrtf(err_x) + sqrtf(err_y); ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] Download dash content with byte range info
--- libavformat/dashdec.c | 38 -- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..3798649 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,24 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * get_Fragment(char *range) +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +if (!seg) +return NULL; + +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset; +} + +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -530,33 +548,40 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = get_Fragment(range_val); if (!rep->init_section) { xmlFree(initialization_val); +xmlFree(range_val); return AVERROR(ENOMEM); } rep->init_section->url = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, initialization_val); + if (!rep->init_section->url) { av_free(rep->init_section); xmlFree(initialization_val); +xmlFree(range_val); return AVERROR(ENOMEM); } -rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = get_Fragment(range_val); if (!seg) { xmlFree(media_val); +xmlFree(range_val); return AVERROR(ENOMEM); } seg->url = get_content_url(baseurl_nodes, 4, @@ -566,11 +591,12 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati if (!seg->url) { av_free(seg); xmlFree(media_val); +xmlFree(range_val); return AVERROR(ENOMEM); } -seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault)
Cleaned the code up. From: ffmpeg-devel on behalf of Carl Eugen Hoyos Sent: November 17, 2017 5:24 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault) 2017-11-17 1:55 GMT+01:00 Colin NG : > Excluded the fix for byte range issue and update some coding style issues. > +if (pb) av_freep(pb); The if() should be unnecessary. Please avoid adding empty lines in unrelated parts of the file and while there, try to fix "if (condition) {" to "if (condition) {" (one space). Carl Eugen ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ffmpeg-devel Info Page<http://ffmpeg.org/mailman/listinfo/ffmpeg-devel> ffmpeg.org This list is about FFmpeg development discussions and patches; but not for bug-reports. Please read the Code-of-conduct. To see the collection of prior postings to ... diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 671ae9d..9bdfefd 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static char * ishttp(char *url) { +char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +av_freep(pb); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -640,6 +647,74 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +int i; +char *text; +char tmp_str[MAX_URL_SIZE]; +char tmp_str_2[MAX_URL_SIZE]; + +char *path = av_mallocz(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/"))) { +nameSize = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url)-nameSize+1); + +int rootId = 0; +xmlNodePtr *node = NULL; +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) { +if (!(node = baseurl_nodes[rootId])) continue; +if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +int size = strlen(root_url); +char *isRootHttp= ishttp(root_url); + +char token ='/'; +if (strncmp(&root_url[size-1],&token, 1) != 0) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i==rootId) continue; +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, strlen(tmp_str)); + +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size+1); +} +int start = (strncmp(text, &token, 1) == 0) ? 1: 0; +memset(tmp_str_2, 0, strlen(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlFree(text); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +} +} + +av_free(path); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -699,6 +774,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[2] = adaptionset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; +resolve_content_path(s, url, baseurl_nodes, 4); + if (representation_segmenttemplate_node || fragment_template_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; @@ -994,6 +1071,9 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
[FFmpeg-devel] [PATCH] Download dash content with byte range info
--- libavformat/dashdec.c | 39 +-- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..671ae9d 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,25 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * get_Fragment(char *range) +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +if (!seg) +return NULL; + +memset(seg, 0, sizeof(struct fragment)); +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset; +} + +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -530,33 +549,40 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = get_Fragment(range_val); if (!rep->init_section) { xmlFree(initialization_val); +xmlFree(range_val); return AVERROR(ENOMEM); } rep->init_section->url = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, initialization_val); + if (!rep->init_section->url) { av_free(rep->init_section); xmlFree(initialization_val); +xmlFree(range_val); return AVERROR(ENOMEM); } -rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = get_Fragment(range_val); if (!seg) { xmlFree(media_val); +xmlFree(range_val); return AVERROR(ENOMEM); } seg->url = get_content_url(baseurl_nodes, 4, @@ -566,11 +592,12 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati if (!seg->url) { av_free(seg); xmlFree(media_val); +xmlFree(range_val); return AVERROR(ENOMEM); } -seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] Download dash content with byte range info
Fixed the range_val leak problem. From: ffmpeg-devel on behalf of Michael Niedermayer Sent: November 17, 2017 12:15 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] Download dash content with byte range info On Thu, Nov 16, 2017 at 08:33:35PM +, Colin NG wrote: > --- > libavformat/dashdec.c | 32 +--- > 1 file changed, 25 insertions(+), 7 deletions(-) > > diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c > index 0e3afd2..33255f2 100644 > --- a/libavformat/dashdec.c > +++ b/libavformat/dashdec.c > @@ -522,6 +522,22 @@ static enum AVMediaType get_content_type(xmlNodePtr node) > return type; > } > > +static struct fragment * get_Fragment(char *range) { > +struct fragment * seg = av_mallocz(sizeof(struct fragment)); > + > +if (!seg) > +return NULL; > + > +seg->size = -1; > +if (range) { > +char *str_end_offset; > +char *str_offset = av_strtok(range, "-", &str_end_offset); > +seg->url_offset = strtoll(str_offset, NULL, 10); > +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset+1; > +} > +return seg; > +} > + > static int parse_manifest_segmenturlnode(AVFormatContext *s, struct > representation *rep, > xmlNodePtr fragmenturl_node, > xmlNodePtr *baseurl_nodes, > @@ -530,11 +546,13 @@ static int > parse_manifest_segmenturlnode(AVFormatContext *s, struct representati > { > char *initialization_val = NULL; > char *media_val = NULL; > +char *range_val = NULL; > > if (!av_strcasecmp(fragmenturl_node->name, (const char > *)"Initialization")) { > initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); > -if (initialization_val) { > -rep->init_section = av_mallocz(sizeof(struct fragment)); > +range_val = xmlGetProp(fragmenturl_node, "range"); > +if (initialization_val || range_val) { > +rep->init_section = get_Fragment(range_val); > if (!rep->init_section) { > xmlFree(initialization_val); > return AVERROR(ENOMEM); > @@ -548,13 +566,14 @@ static int > parse_manifest_segmenturlnode(AVFormatContext *s, struct representati > xmlFree(initialization_val); > return AVERROR(ENOMEM); > } > -rep->init_section->size = -1; > xmlFree(initialization_val); > +xmlFree(range_val); > } > } else if (!av_strcasecmp(fragmenturl_node->name, (const char > *)"SegmentURL")) { > media_val = xmlGetProp(fragmenturl_node, "media"); > -if (media_val) { > -struct fragment *seg = av_mallocz(sizeof(struct fragment)); > +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); > +if (media_val || range_val) { > +struct fragment *seg = get_Fragment(range_val); > if (!seg) { > xmlFree(media_val); > return AVERROR(ENOMEM); > @@ -568,15 +587,14 @@ static int > parse_manifest_segmenturlnode(AVFormatContext *s, struct representati > xmlFree(media_val); > return AVERROR(ENOMEM); > } > -seg->size = -1; > dynarray_add(&rep->fragments, &rep->n_fragments, seg); > xmlFree(media_val); > +xmlFree(range_val); > } I think this is leaking range_val in some error paths [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Democracy is the form of government in which you can choose your dictator From 61c79e979ba7586b7fbf98e674dfcd4d4adc5797 Mon Sep 17 00:00:00 2001 From: Colin Ng Date: Fri, 17 Nov 2017 13:59:13 -0800 Subject: [PATCH] Download dash content with byte range info --- libavformat/dashdec.c | 38 -- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..8a575d5 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,25 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * get_Fragment(char *range) +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +if (!seg) +return NULL; + +memset(seg, 0, sizeof(struct fragment)); +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_off
Re: [FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault)
Excluded the fix for byte range issue and update some coding style issues. From: Colin NG Sent: November 15, 2017 10:58 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault) Have submitted already for the byte range issue in another email with title "Download dash content with byte range info" From: ffmpeg-devel on behalf of Carl Eugen Hoyos Sent: November 15, 2017 10:54 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault) 2017-11-15 3:54 GMT+01:00 Colin NG : > - Add a function to handle the base URL Processing described in section 5.6.5 > of IEC_23009-1. > > - Fix for downloading dash content with byte range info As said: If these are two separate issues, please send two patches. Use tools/patcheck to check your patch for many style issues. (No Changelog entry necessary.) Try to avoid if ((var1 = var2) > 1), instead add an additional line. Carl Eugen ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ffmpeg-devel Info Page<http://ffmpeg.org/mailman/listinfo/ffmpeg-devel> ffmpeg.org This list is about FFmpeg development discussions and patches; but not for bug-reports. Please read the Code-of-conduct. To see the collection of prior postings to ... diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..4d89374 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,11 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static char * ishttp(char *url) { +char *proto_name = avio_find_protocol_name(url); +return av_strstart(proto_name, "http", NULL); +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +397,10 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +if (pb) av_freep(pb); + // set_httpheader_options(c, &tmp); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -613,6 +621,77 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } + +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +int i; +char *text; +char tmp_str[MAX_URL_SIZE]; +char tmp_str_2[MAX_URL_SIZE]; + +char *path = av_mallocz(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/"))) { +nameSize = strlen(mpdName); +} + +av_strlcpy (path, url, strlen(url)-nameSize+1 ); + +int rootId = 0; +xmlNodePtr *node = NULL; +char *proto_name = NULL; +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) { +if (!(node = baseurl_nodes[rootId])) continue; + + if (ishttp(xmlNodeGetContent(node))) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +int size = strlen(root_url); +char *isRootHttp= ishttp(root_url); + +char token ='/'; +if (strncmp(&root_url[size-1],&token, 1) != 0) { +av_strlcat(root_url, "/", size+2); +size+=2; +} + +for (i = 0; i < n_baseurl_nodes; ++i) { +if (i==rootId) continue; +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) { +memset(tmp_str, 0, sizeof(tmp_str)); + +if (!ishttp(text) && isRootHttp) { +av_strlcpy(tmp_str, root_url, size+1); +} +int start = (strncmp(text, &token, 1) == 0) ? 1: 0; +memset(tmp_str_2, 0, sizeof(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlFree(text); +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +} +} + +av_free(path); +return updated; + +} static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset
[FFmpeg-devel] [PATCH] Download dash content with byte range info
--- libavformat/dashdec.c | 32 +--- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..33255f2 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,22 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * get_Fragment(char *range) { +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +if (!seg) +return NULL; + +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset+1; +} +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -530,11 +546,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = get_Fragment(range_val); if (!rep->init_section) { xmlFree(initialization_val); return AVERROR(ENOMEM); @@ -548,13 +566,14 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati xmlFree(initialization_val); return AVERROR(ENOMEM); } -rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = get_Fragment(range_val); if (!seg) { xmlFree(media_val); return AVERROR(ENOMEM); @@ -568,15 +587,14 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati xmlFree(media_val); return AVERROR(ENOMEM); } -seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } return 0; } - static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representation *rep, xmlNodePtr fragment_timeline_node) { -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [Patch] Download dash content with byte range info
Made change suggested by Carl and add some minor fixes. From: ffmpeg-devel on behalf of Carl Eugen Hoyos Sent: November 15, 2017 5:37 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [Patch] Download dash content with byte range info 2017-11-15 22:00 GMT+01:00 Colin NG : > This patch is partial fix for ticket 6658 (Dash demuxer segfault). > +static struct fragment * get_Fragment(char *range) { > +struct fragment * seg = av_mallocz(sizeof(struct fragment)); Please make it (code-style): ... fragment *get_Fragment... ... fragment *seg =... > +if (!seg) > +goto finish; No. You can "return NULL;" but since this is a little misleading, it may be better to return AVERROR(ENOMEM) and instead of the existing check for NULL below, check for "< 0". Carl Eugen ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ffmpeg-devel Info Page<http://ffmpeg.org/mailman/listinfo/ffmpeg-devel> ffmpeg.org This list is about FFmpeg development discussions and patches; but not for bug-reports. Please read the Code-of-conduct. To see the collection of prior postings to ... diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..33255f2 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,22 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * get_Fragment(char *range) { +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +if (!seg) +return NULL; + +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset+1; +} +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -530,11 +546,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = get_Fragment(range_val); if (!rep->init_section) { xmlFree(initialization_val); return AVERROR(ENOMEM); @@ -548,13 +566,14 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati xmlFree(initialization_val); return AVERROR(ENOMEM); } -rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = get_Fragment(range_val); if (!seg) { xmlFree(media_val); return AVERROR(ENOMEM); @@ -568,15 +587,14 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati xmlFree(media_val); return AVERROR(ENOMEM); } -seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } return 0; } - static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representation *rep, xmlNodePtr fragment_timeline_node) { ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [Patch] Download dash content with byte range info
This patch is partial fix for ticket 6658 (Dash demuxer segfault). From: ffmpeg-devel on behalf of Steven Liu Sent: November 15, 2017 2:58 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [Patch] Download dash content with byte range info 2017-11-15 10:26 GMT+08:00 Colin NG : > Please ignore the previous "patch" email. > > > > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..68196e9 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,22 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * getFragment(char *range) Camel-Case code style, please use name looks like : get_fragment +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); check the seg , if av_mallocz is failed, it will error; + +memset(seg, 0, sizeof(struct fragment)); unnecessary memset, because av_mallocz is set seg to 0 already. +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset; +} + +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -530,11 +546,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = getFragment(range_val);// byte range on if (!rep->init_section) { xmlFree(initialization_val); return AVERROR(ENOMEM); @@ -550,11 +568,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati } rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = getFragment(range_val);// byte range on if (!seg) { xmlFree(media_val); return AVERROR(ENOMEM); @@ -571,12 +591,12 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } return 0; } - static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representation *rep, xmlNodePtr fragment_timeline_node) { ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ffmpeg-devel Info Page<http://ffmpeg.org/mailman/listinfo/ffmpeg-devel> ffmpeg.org This list is about FFmpeg development discussions and patches; but not for bug-reports. Please read the Code-of-conduct. To see the collection of prior postings to ... diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..0bc0f06 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,23 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * get_Fragment(char *range) { +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +if (!seg) +goto finish; + +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset; +
Re: [FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault)
Have submitted already for the byte range issue in another email with title "Download dash content with byte range info" From: ffmpeg-devel on behalf of Carl Eugen Hoyos Sent: November 15, 2017 10:54 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault) 2017-11-15 3:54 GMT+01:00 Colin NG : > - Add a function to handle the base URL Processing described in section 5.6.5 > of IEC_23009-1. > > - Fix for downloading dash content with byte range info As said: If these are two separate issues, please send two patches. Use tools/patcheck to check your patch for many style issues. (No Changelog entry necessary.) Try to avoid if ((var1 = var2) > 1), instead add an additional line. Carl Eugen ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ffmpeg-devel Info Page<http://ffmpeg.org/mailman/listinfo/ffmpeg-devel> ffmpeg.org This list is about FFmpeg development discussions and patches; but not for bug-reports. Please read the Code-of-conduct. To see the collection of prior postings to ... ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault)
- Add a function to handle the base URL Processing described in section 5.6.5 of IEC_23009-1. - Fix for downloading dash content with byte range info diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..0be8a49 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,6 +148,10 @@ static uint64_t get_current_time_in_sec(void) return av_gettime() / 100; } +static int ishttp(char *url) { +return (av_strstart(url, "http://";, NULL) || av_strstart(url, "https://";, NULL)) ; +} + static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) { struct tm timeinfo; @@ -392,7 +396,10 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +if (pb) av_freep(pb); +set_httpheader_options(c, &tmp); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -522,6 +529,22 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * getFragment(char *range) +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +memset(seg, 0, sizeof(struct fragment)); +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset; +} + +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -530,11 +553,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = getFragment(range_val);// byte range on if (!rep->init_section) { xmlFree(initialization_val); return AVERROR(ENOMEM); @@ -550,11 +575,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati } rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = getFragment(range_val);// byte range on if (!seg) { xmlFree(media_val); return AVERROR(ENOMEM); @@ -571,6 +598,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } @@ -613,6 +641,86 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat return 0; } + +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +int i; +char *text; +char tmp_str[MAX_URL_SIZE]; +char tmp_str_2[MAX_URL_SIZE]; + +char *path = av_mallocz(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/")) != NULL) +{ +nameSize = strlen(mpdName); +} + +memset(path, 0, MAX_URL_SIZE* sizeof(char)); +av_strlcpy (path, url, strlen(url)-nameSize+1 ); + +int rootId = 0; +xmlNodePtr *node = NULL; +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) +{ +if ((node = baseurl_nodes[rootId])== NULL) continue; + +if (ishttp(xmlNodeGetContent(node)) == TRUE) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (nod
[FFmpeg-devel] [Patch] Download dash content with byte range info
Please ignore the previous "patch" email. diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..68196e9 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,22 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * getFragment(char *range) +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +memset(seg, 0, sizeof(struct fragment)); +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(str_offset, NULL, 10); +seg->size = strtoll(str_end_offset, NULL, 10) -seg->url_offset; +} + +return seg; +} + static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, xmlNodePtr fragmenturl_node, xmlNodePtr *baseurl_nodes, @@ -530,11 +546,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati { char *initialization_val = NULL; char *media_val = NULL; +char *range_val = NULL; if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); -if (initialization_val) { -rep->init_section = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "range"); +if (initialization_val || range_val) { +rep->init_section = getFragment(range_val);// byte range on if (!rep->init_section) { xmlFree(initialization_val); return AVERROR(ENOMEM); @@ -550,11 +568,13 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati } rep->init_section->size = -1; xmlFree(initialization_val); +xmlFree(range_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); -if (media_val) { -struct fragment *seg = av_mallocz(sizeof(struct fragment)); +range_val = xmlGetProp(fragmenturl_node, "mediaRange"); +if (media_val || range_val) { +struct fragment *seg = getFragment(range_val);// byte range on if (!seg) { xmlFree(media_val); return AVERROR(ENOMEM); @@ -571,12 +591,12 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); xmlFree(media_val); +xmlFree(range_val); } } return 0; } - static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representation *rep, xmlNodePtr fragment_timeline_node) { ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [Patch] Download dash content with byte range info
diff --git a/doc/examples/Makefile b/doc/examples/Makefile index 58afd71..bff4af6 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -1,3 +1,16 @@ +# use pkg-config for getting CFLAGS and LDLIBS +FFMPEG_LIBS=libavdevice\ +libavformat\ +libavfilter\ +libavcodec \ +libswresample \ +libswscale \ +libavutil \ + +CFLAGS += -Wall -g +CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS) +LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS) + EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE) += avio_dir_cmd EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio @@ -19,6 +32,7 @@ EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding +EXAMPLES-$(CONFIG_SAMPLE_EXAMPLE) += sample EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF)) EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF)) diff --git a/doc/examples/avio_reading.c b/doc/examples/avio_reading.c index 7860fd5..c77b8f9 100644 --- a/doc/examples/avio_reading.c +++ b/doc/examples/avio_reading.c @@ -39,6 +39,15 @@ struct buffer_data { size_t size; ///< size left in the buffer }; +static int isLocal(char *url) +{ + if (av_strstart(url, "http://";, NULL) || av_strstart(url, "https://";, NULL)) + { + return FALSE; + } + return TRUE; +} + static int read_packet(void *opaque, uint8_t *buf, int buf_size) { struct buffer_data *bd = (struct buffer_data *)opaque; @@ -78,7 +87,28 @@ int main(int argc, char *argv[]) av_register_all(); /* slurp file content into buffer */ -ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL); + + if (isLocal(input_filename) == TRUE) + { + ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL); + } + else + { + AVIOContext *in = NULL; + + ret = avio_open2(&in, input_filename, AVIO_FLAG_READ, NULL, NULL); + + buffer_size = avio_size(in); + + if (buffer_size <= 0) { + buffer_size = 8 * 1024; + } + + if (buffer = av_mallocz(buffer_size) == NULL) { + return AVERROR(ENOMEM); + } + buffer_size = avio_read(in, buffer, buffer_size); + } if (ret < 0) goto end; diff --git a/libavcodec/dsd.c b/libavcodec/dsd.c index 9104f38..6742f53 100644 --- a/libavcodec/dsd.c +++ b/libavcodec/dsd.c @@ -21,7 +21,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + #include "libavcodec/internal.h" +#include "libavutil/reverse.h" #include "libavcodec/mathops.h" #include "avcodec.h" #include "dsd_tablegen.h" diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 1b332a7..2d77088 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -24,6 +24,8 @@ * @author Konstantin Shishkov */ +#include "libavutil/reverse.h" + #include "config.h" #if CONFIG_ZLIB #include diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index 93fd0f4..2cfe24b 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -21,6 +21,8 @@ #include "libavutil/mathematics.h" #include "libavutil/imgutils.h" +#include "libavutil/intmath.h" + #include "avcodec.h" #include "get_bits.h" #include "bytestream.h" diff --git a/libavdevice/v4l2-common.c b/libavdevice/v4l2-common.c index 196c09b..80cd524 100644 --- a/libavdevice/v4l2-common.c +++ b/libavdevice/v4l2-common.c @@ -43,9 +43,9 @@ const struct fmt_map ff_fmt_conversion_table[] = { { AV_PIX_FMT_NV12,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12}, { AV_PIX_FMT_NONE,AV_CODEC_ID_MJPEG,V4L2_PIX_FMT_MJPEG }, { AV_PIX_FMT_NONE,AV_CODEC_ID_MJPEG,V4L2_PIX_FMT_JPEG}, -#ifdef V4L2_PIX_FMT_H264 +//#ifdef V4L2_PIX_FMT_H264 { AV_PIX_FMT_NONE,AV_CODEC_ID_H264, V4L2_PIX_FMT_H264}, -#endif +//#endif #ifdef V4L2_PIX_FMT_MPEG4 { AV_PIX_FMT_NONE,AV_CODEC_ID_MPEG4,V4L2_PIX_FMT_MPEG4 }, #endif diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0e3afd2..68196e9 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -522,6 +522,22 @@ static enum AVMediaType get_content_type(xmlNodePtr node) return type; } +static struct fragment * getFragment(char *range) +{ +struct fragment * seg = av_mallocz(sizeof(struct fragment)); + +memset(seg, 0, sizeof(struct fragment)); +seg->size = -1; +if (range) { +char *str_end_offset; +char *str_offset = av_strtok(range, "-", &str_end_offset); +seg->url_offset = strtoll(s
[FFmpeg-devel] [Patch] Fix for ticket 6658 (Dash demuxer segfault)
- Add a function to handle the base URL Processing described in section 5.6.5 of IEC_23009-1. - Fix for downloading content with byte range selection diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index f63f1ff..19ef6f8 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -349,6 +349,16 @@ static void update_options(char **dest, const char *name, void *src) av_freep(dest); } +static int isLocal(char *url) { + +if (av_strstart(url, "http://";, NULL) || av_strstart(url, "https://";, NULL)) +{ +return FALSE; +} + +return TRUE; +} + static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, AVDictionary *opts, AVDictionary *opts2, int *is_http) { @@ -392,7 +402,16 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; -ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); +{ +av_freep(pb); +AVDictionary *opts = NULL; +set_httpheader_options(c, opts); +ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &opts); +av_dict_free(&opts); +if (ret < 0) +return ret; +} + if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -416,11 +435,156 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, return ret; } -static char *get_content_url(xmlNodePtr *baseurl_nodes, - int n_baseurl_nodes, - char *rep_id_val, - char *rep_bandwidth_val, - char *val) + +static int resolve_content_path(AVFormatContext *s, const char *url, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) { + +int i; +char *text; +char tmp_str[MAX_URL_SIZE]; +char tmp_str_2[MAX_URL_SIZE]; + +char *path = malloc(MAX_URL_SIZE); +int nameSize = 0; +int updated = 0; + +av_strlcpy(tmp_str, url, strlen(url)+1); +char *mpdName = strtok (tmp_str," /"); + +while ((mpdName =strtok (NULL, "/")) != NULL) +{ +nameSize = strlen(mpdName); +} + +memset(path, 0, MAX_URL_SIZE* sizeof(char)); +av_strlcpy (path, url, strlen(url)-nameSize+1 ); + +int rootId = 0; +xmlNodePtr *node = NULL; +for (rootId = n_baseurl_nodes-1; rootId >0; rootId--) +{ +if ((node = baseurl_nodes[rootId])== NULL) continue; + +if (isLocal(xmlNodeGetContent(node)) == FALSE) { +break; +} +} + +node = baseurl_nodes[rootId]; +char *baseurl = xmlNodeGetContent(node); +char *root_url = (!av_strcasecmp(baseurl, ""))? path: baseurl; + +if (node) { +xmlNodeSetContent(node, root_url); +} + +int size = strlen(root_url); +int isRootLocal = isLocal(root_url); + +char token ='/'; +if (strncmp(&root_url[size-1],&token, 1) != 0) +{ +strcat(root_url, "/"); +size++; +} + +for (i = 0; i < n_baseurl_nodes; ++i) +{ +if (i==rootId) continue; +text = xmlNodeGetContent(baseurl_nodes[i]); +if (text) +{ +memset(tmp_str, 0, sizeof(tmp_str)); + +if (isLocal(text) == TRUE && isRootLocal == FALSE) +{ +av_strlcpy(tmp_str, root_url, size+1); +} +if (text) +{ +int start = (strncmp(text, &token, 1) == 0) ? 1: 0; +memset(tmp_str_2, 0, sizeof(tmp_str_2)); +av_strlcat(tmp_str, text+start, MAX_URL_SIZE); +xmlFree(text); +} +xmlNodeSetContent(baseurl_nodes[i], tmp_str); +updated = 1; +} +} + +free(path); +return updated; + +} + +static int av_strchr(const char *str, char tok) { + +char * pch; +int *pos; +int ctr = 0; +pch=strchr(str, tok); +pos = av_mallocz( strlen(str)*sizeof(int)); +while (pch!=NULL) { +pos[ctr] = pch-str+1; +pch=strchr(pch+1, tok); +ctr++; +} + +return pos[ctr-2]; +} +static void updatePath(AVFormatContext *s, char *baseURL, char *locale) { + +int len = strlen(baseURL); +int upDir=0; + +if (!locale || isLocal(locale) == FALSE) +return; + +char curDirChar[] = "./"; +char parentDirChar[] = "../"; + +while (av_strstart(locale, curDirChar, NULL) == TRUE) { +locale = av_strireplace(locale, curDirChar, ""); +} + +while (av_strstart(locale, parentDirChar, NULL) == TRUE) { +locale = av_strireplace(locale, parentDirChar, ""); +upDir++; +} + +char *pch = strchr (baseURL, '/'); + +if (upDir == 0 || pch == NULL) +goto finish; + +int depth = 0; +int *marker = (int *)av_mallocz(strlen(baseURL)*sizeof(int)); + +memset(marker, 0, str