History

Merge commit '0c73a5a53cc97f4291bbe9e1e68226edf6161744'

* commit '0c73a5a53cc97f4291bbe9e1e68226edf6161744': hls: Save and forward avio options Conflicts: libavformat/hls.c

Michael Niedermayer committed 11 years ago

Commit ba12ba82 parents 8e67599 0c73a5a1 file · +89 −8Browse files

Unified · Split

libavformat/hls.c+89−8
@@ -182,6 +182,7 @@ typedef struct HLSContext { · 181 unmodified lines
182 char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context182 char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
183 char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context183 char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context
184 char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context184 char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context
185 AVDictionary *avio_opts;
185} HLSContext;186} HLSContext;
186 187
187static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)188static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -494,6 +495,53 @@ static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url · 306 unmodified lines
494 495
495/* pls = NULL => Master Playlist or parentless Media Playlist496/* pls = NULL => Master Playlist or parentless Media Playlist
496 * pls = !NULL => parented Media Playlist, playlist+variant allocated */497 * pls = !NULL => parented Media Playlist, playlist+variant allocated */
498static int open_in(HLSContext *c, AVIOContext **in, const char *url)
499{
500 AVDictionary *tmp = NULL;
501 int ret;
502
503 av_dict_copy(&tmp, c->avio_opts, 0);
504
505 ret = avio_open2(in, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
506
507 av_dict_free(&tmp);
508 return ret;
509}
510
511static int url_connect(struct playlist *pls, AVDictionary *opts, AVDictionary *opts2)
512{
513 AVDictionary *tmp = NULL;
514 int ret;
515
516 av_dict_copy(&tmp, opts, 0);
517 av_dict_copy(&tmp, opts2, 0);
518
519 av_opt_set_dict(pls->input, &tmp);
520
521 if ((ret = ffurl_connect(pls->input, NULL)) < 0) {
522 ffurl_close(pls->input);
523 pls->input = NULL;
524 }
525
526 av_dict_free(&tmp);
527 return ret;
528}
529
530static int open_url(HLSContext *c, URLContext **uc, const char *url, AVDictionary *opts)
531{
532 AVDictionary *tmp = NULL;
533 int ret;
534
535 av_dict_copy(&tmp, c->avio_opts, 0);
536 av_dict_copy(&tmp, opts, 0);
537
538 ret = ffurl_open(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
539
540 av_dict_free(&tmp);
541
542 return ret;
543}
544
497static int parse_playlist(HLSContext *c, const char *url,545static int parse_playlist(HLSContext *c, const char *url,
498 struct playlist *pls, AVIOContext *in)546 struct playlist *pls, AVIOContext *in)
499{547{
@@ -513,6 +561,7 @@ static int parse_playlist(HLSContext *c, const char *url, · 13 unmodified lines
513 char tmp_str[MAX_URL_SIZE];561 char tmp_str[MAX_URL_SIZE];
514 562
515 if (!in) {563 if (!in) {
564#if 1
516 AVDictionary *opts = NULL;565 AVDictionary *opts = NULL;
517 close_in = 1;566 close_in = 1;
518 /* Some HLS servers don't like being sent the range header */567 /* Some HLS servers don't like being sent the range header */
@@ -528,6 +577,12 @@ static int parse_playlist(HLSContext *c, const char *url, · 9 unmodified lines
528 av_dict_free(&opts);577 av_dict_free(&opts);
529 if (ret < 0)578 if (ret < 0)
530 return ret;579 return ret;
580#else
581 ret = open_in(c, &in, url);
582 if (ret < 0)
583 return ret;
584 close_in = 1;
585#endif
531 }586 }
532 587
533 if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)588 if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
@@ -940,15 +995,13 @@ static int open_input(HLSContext *c, struct playlist *pls) · 406 unmodified lines
940 seg->url, seg->url_offset, pls->index);995 seg->url, seg->url_offset, pls->index);
941 996
942 if (seg->key_type == KEY_NONE) {997 if (seg->key_type == KEY_NONE) {
943 ret = ffurl_open(&pls->input, seg->url, AVIO_FLAG_READ,998 ret = open_url(pls->parent->priv_data, &pls->input, seg->url, opts);
944 &pls->parent->interrupt_callback, &opts);
945
946 } else if (seg->key_type == KEY_AES_128) {999 } else if (seg->key_type == KEY_AES_128) {
1000// HLSContext *c = var->parent->priv_data;
947 char iv[33], key[33], url[MAX_URL_SIZE];1001 char iv[33], key[33], url[MAX_URL_SIZE];
948 if (strcmp(seg->key, pls->key_url)) {1002 if (strcmp(seg->key, pls->key_url)) {
949 URLContext *uc;1003 URLContext *uc;
950 if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,1004 if (open_url(pls->parent->priv_data, &uc, seg->key, opts2) == 0) {
951 &pls->parent->interrupt_callback, &opts2) == 0) {
952 if (ffurl_read_complete(uc, pls->key, sizeof(pls->key))1005 if (ffurl_read_complete(uc, pls->key, sizeof(pls->key))
953 != sizeof(pls->key)) {1006 != sizeof(pls->key)) {
954 av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",1007 av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
@@ -970,15 +1023,14 @@ static int open_input(HLSContext *c, struct playlist *pls) · 15 unmodified lines
970 snprintf(url, sizeof(url), "crypto+%s", seg->url);1023 snprintf(url, sizeof(url), "crypto+%s", seg->url);
971 else1024 else
972 snprintf(url, sizeof(url), "crypto:%s", seg->url);1025 snprintf(url, sizeof(url), "crypto:%s", seg->url);
1026
973 if ((ret = ffurl_alloc(&pls->input, url, AVIO_FLAG_READ,1027 if ((ret = ffurl_alloc(&pls->input, url, AVIO_FLAG_READ,
974 &pls->parent->interrupt_callback)) < 0)1028 &pls->parent->interrupt_callback)) < 0)
975 goto cleanup;1029 goto cleanup;
976 av_opt_set(pls->input->priv_data, "key", key, 0);1030 av_opt_set(pls->input->priv_data, "key", key, 0);
977 av_opt_set(pls->input->priv_data, "iv", iv, 0);1031 av_opt_set(pls->input->priv_data, "iv", iv, 0);
978 1032
979 if ((ret = ffurl_connect(pls->input, &opts)) < 0) {1033 if ((ret = url_connect(pls, c->avio_opts, opts)) < 0) {
980 ffurl_close(pls->input);
981 pls->input = NULL;
982 goto cleanup;1034 goto cleanup;
983 }1035 }
984 ret = 0;1036 ret = 0;
@@ -1254,6 +1306,26 @@ static int select_cur_seq_no(HLSContext *c, struct playlist *pls) · 269 unmodified lines
1254 return pls->start_seq_no;1306 return pls->start_seq_no;
1255}1307}
1256 1308
1309static int save_avio_options(AVFormatContext *s)
1310{
1311 HLSContext *c = s->priv_data;
1312 const char *opts[] = { "headers", "user_agent", "user-agent", "cookies", NULL }, **opt = opts;
1313 uint8_t *buf;
1314 int ret = 0;
1315
1316 while (*opt) {
1317 if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
1318 ret = av_dict_set(&c->avio_opts, *opt, buf,
1319 AV_DICT_DONT_STRDUP_VAL);
1320 if (ret < 0)
1321 return ret;
1322 }
1323 opt++;
1324 }
1325
1326 return ret;
1327}
1328
1257static int hls_read_header(AVFormatContext *s)1329static int hls_read_header(AVFormatContext *s)
1258{1330{
1259 URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;1331 URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;
@@ -1281,6 +1353,12 @@ static int hls_read_header(AVFormatContext *s) · 21 unmodified lines
1281 if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)1353 if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
1282 goto fail;1354 goto fail;
1283 1355
1356 if ((ret = save_avio_options(s)) < 0)
1357 goto fail;
1358
1359 /* Some HLS servers don't like being sent the range header */
1360 av_dict_set(&c->avio_opts, "seekable", "0", 0);
1361
1284 if (c->n_variants == 0) {1362 if (c->n_variants == 0) {
1285 av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");1363 av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
1286 ret = AVERROR_EOF;1364 ret = AVERROR_EOF;
@@ -1631,6 +1709,9 @@ static int hls_close(AVFormatContext *s) · 344 unmodified lines
1631 free_playlist_list(c);1709 free_playlist_list(c);
1632 free_variant_list(c);1710 free_variant_list(c);
1633 free_rendition_list(c);1711 free_rendition_list(c);
1712
1713 av_dict_free(&c->avio_opts);
1714
1634 return 0;1715 return 0;
1635}1716}
1636 1717

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t