mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 12:36:41 +08:00 
			
		
		
		
	Merge remote-tracking branch 'qatar/master'
* qatar/master: (22 commits) configure: add check for w32threads to enable it automatically rtmp: do not hardcode invoke numbers cinepack: return non-generic errors fate-lavf-ts: use -mpegts_transport_stream_id option. Add an APIchanges entry and a minor bump for avio changes. avio: Mark the old interrupt callback mechanism as deprecated avplay: Set the new interrupt callback avconv: Set new interrupt callbacks for all AVFormatContexts, use avio_open2() everywhere cinepak: remove redundant coordinate checks cinepak: check strip_size cinepak, simplify, use AV_RB24() cinepak: simplify, use FFMIN() cinepak: Fix division by zero, ask for sample if encoded_buf_size is 0 applehttp: Fix seeking in streams not starting at DTS=0 http: Don't use the normal http proxy mechanism for https tls: Handle connection via a http proxy http: Reorder two code blocks http: Add a new protocol for opening connections via http proxies http: Split out the non-chunked buffer reading part from http_read segafilm: add support for raw videos ... Conflicts: avconv.c configure doc/APIchanges libavcodec/cinepak.c libavformat/applehttp.c libavformat/version.h tests/lavf-regression.sh tests/ref/lavf/ts Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
							
								
								
									
										28
									
								
								avconv.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								avconv.c
									
									
									
									
									
								
							| @@ -588,12 +588,14 @@ static int read_key(void) | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
| static int decode_interrupt_cb(void) | ||||
| static int decode_interrupt_cb(void *ctx) | ||||
| { | ||||
|     q_pressed += read_key() == 'q'; | ||||
|     return q_pressed > 1; | ||||
| } | ||||
|  | ||||
| static const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; | ||||
|  | ||||
| void exit_program(int ret) | ||||
| { | ||||
|     int i; | ||||
| @@ -2336,6 +2338,7 @@ static int transcode_init(OutputFile *output_files, | ||||
|     /* open files and write file headers */ | ||||
|     for (i = 0; i < nb_output_files; i++) { | ||||
|         os = output_files[i].ctx; | ||||
|         os->interrupt_callback = int_cb; | ||||
|         if (avformat_write_header(os, &output_files[i].opts) < 0) { | ||||
|             snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i); | ||||
|             ret = AVERROR(EINVAL); | ||||
| @@ -3010,7 +3013,7 @@ static void dump_attachment(AVStream *st, const char *filename) | ||||
|  | ||||
|     assert_file_overwrite(filename); | ||||
|  | ||||
|     if ((ret = avio_open (&out, filename, AVIO_FLAG_WRITE)) < 0) { | ||||
|     if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) { | ||||
|         av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n", | ||||
|                filename); | ||||
|         exit_program(1); | ||||
| @@ -3068,6 +3071,7 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena | ||||
|         av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0); | ||||
|  | ||||
|     ic->flags |= AVFMT_FLAG_NONBLOCK; | ||||
|     ic->interrupt_callback = int_cb; | ||||
|  | ||||
|     /* open the input file with generic libav function */ | ||||
|     err = avformat_open_input(&ic, filename, file_iformat, &format_opts); | ||||
| @@ -3197,12 +3201,12 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV | ||||
|         if (codec_name) { | ||||
|             snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], | ||||
|                      i != 1 ? "" : "/.avconv", codec_name, preset_name); | ||||
|             ret = avio_open(s, filename, AVIO_FLAG_READ); | ||||
|             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); | ||||
|         } | ||||
|         if (ret) { | ||||
|             snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], | ||||
|                      i != 1 ? "" : "/.avconv", preset_name); | ||||
|             ret = avio_open(s, filename, AVIO_FLAG_READ); | ||||
|             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); | ||||
|         } | ||||
|     } | ||||
|     return ret; | ||||
| @@ -3588,8 +3592,9 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata) | ||||
| static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename) | ||||
| { | ||||
|     int i, err; | ||||
|     AVFormatContext *ic = NULL; | ||||
|     AVFormatContext *ic = avformat_alloc_context(); | ||||
|  | ||||
|     ic->interrupt_callback = int_cb; | ||||
|     err = avformat_open_input(&ic, filename, NULL, NULL); | ||||
|     if (err < 0) | ||||
|         return err; | ||||
| @@ -3638,6 +3643,7 @@ static void opt_output_file(void *optctx, const char *filename) | ||||
|     } | ||||
|  | ||||
|     file_oformat= oc->oformat; | ||||
|     oc->interrupt_callback = int_cb; | ||||
|  | ||||
|     if (!strcmp(file_oformat->name, "ffm") && | ||||
|         av_strstart(filename, "http:", NULL)) { | ||||
| @@ -3729,7 +3735,7 @@ static void opt_output_file(void *optctx, const char *filename) | ||||
|         const char *p; | ||||
|         int64_t len; | ||||
|  | ||||
|         if ((err = avio_open(&pb, o->attachments[i], AVIO_FLAG_READ)) < 0) { | ||||
|         if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) { | ||||
|             av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n", | ||||
|                    o->attachments[i]); | ||||
|             exit_program(1); | ||||
| @@ -3779,7 +3785,9 @@ static void opt_output_file(void *optctx, const char *filename) | ||||
|         assert_file_overwrite(filename); | ||||
|  | ||||
|         /* open the file */ | ||||
|         if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { | ||||
|         if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, | ||||
|                               &oc->interrupt_callback, | ||||
|                               &output_files[nb_output_files - 1].opts)) < 0) { | ||||
|             print_error(filename, err); | ||||
|             exit_program(1); | ||||
|         } | ||||
| @@ -4350,12 +4358,6 @@ int main(int argc, char **argv) | ||||
|     av_register_all(); | ||||
|     avformat_network_init(); | ||||
|  | ||||
| #if HAVE_ISATTY | ||||
|     if(isatty(STDIN_FILENO)) | ||||
|         avio_set_interrupt_cb(decode_interrupt_cb); | ||||
| #endif | ||||
|  | ||||
|     show_banner(); | ||||
|  | ||||
|     /* parse options */ | ||||
|     parse_options(&o, argc, argv, options, opt_output_file); | ||||
|   | ||||
							
								
								
									
										5
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								configure
									
									
									
									
										vendored
									
									
								
							| @@ -2583,7 +2583,6 @@ case $target_os in | ||||
|             disable network | ||||
|         else | ||||
|             target_os=mingw32 | ||||
|             enable_weak w32threads | ||||
|         fi | ||||
|         LIBTARGET=i386 | ||||
|         if enabled x86_64; then | ||||
| @@ -2999,6 +2998,10 @@ if ! disabled vda; then | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| if ! disabled w32threads && ! enabled pthreads; then | ||||
|     check_func _beginthreadex && enable w32threads | ||||
| fi | ||||
|  | ||||
| # check for some common methods of building with pthread support | ||||
| # do this before the optional library checks as some of them require pthreads | ||||
| if ! disabled pthreads && ! enabled w32threads && ! enabled os2threads; then | ||||
|   | ||||
| @@ -19,6 +19,16 @@ API changes, most recent first: | ||||
| 2011-10-20 - b35e9e1 - lavu 51.22.0 | ||||
|   Add av_strtok() to avstring.h. | ||||
|  | ||||
| 2011-11-13 - lavf 53.15.0 | ||||
|   New interrupt callback API, allowing per-AVFormatContext/AVIOContext | ||||
|   interrupt callbacks. | ||||
|   6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to | ||||
|           AVFormatContext. | ||||
|   1dee0ac Add avio_open2() with additional parameters. Those are | ||||
|           an interrupt callback and an options AVDictionary. | ||||
|           This will allow passing AVOptions to protocols after lavf | ||||
|           54.0. | ||||
|  | ||||
| 2011-11-xx - xxxxxxx - lavu 51.16.0 | ||||
|   Add av_timegm() | ||||
|  | ||||
|   | ||||
							
								
								
									
										29
									
								
								ffmpeg.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								ffmpeg.c
									
									
									
									
									
								
							| @@ -635,11 +635,13 @@ static int read_key(void) | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
| static int decode_interrupt_cb(void) | ||||
| static int decode_interrupt_cb(void *ctx) | ||||
| { | ||||
|     return received_nb_signals > 1; | ||||
| } | ||||
|  | ||||
| static const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; | ||||
|  | ||||
| void av_noreturn exit_program(int ret) | ||||
| { | ||||
|     int i; | ||||
| @@ -2403,6 +2405,7 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, | ||||
|     /* open files and write file headers */ | ||||
|     for (i = 0; i < nb_output_files; i++) { | ||||
|         os = output_files[i].ctx; | ||||
|         os->interrupt_callback = int_cb; | ||||
|         if (avformat_write_header(os, &output_files[i].opts) < 0) { | ||||
|             snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i); | ||||
|             ret = AVERROR(EINVAL); | ||||
| @@ -2495,7 +2498,6 @@ static int transcode(OutputFile *output_files, int nb_output_files, | ||||
|  | ||||
|     if (!using_stdin) { | ||||
|         av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n"); | ||||
|         avio_set_interrupt_cb(decode_interrupt_cb); | ||||
|     } | ||||
|  | ||||
|     timer_start = av_gettime(); | ||||
| @@ -3243,7 +3245,7 @@ static void dump_attachment(AVStream *st, const char *filename) | ||||
|  | ||||
|     assert_file_overwrite(filename); | ||||
|  | ||||
|     if ((ret = avio_open (&out, filename, AVIO_FLAG_WRITE)) < 0) { | ||||
|     if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) { | ||||
|         av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n", | ||||
|                filename); | ||||
|         exit_program(1); | ||||
| @@ -3307,6 +3309,7 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena | ||||
|     ic->subtitle_codec_id= subtitle_codec_name ? | ||||
|         find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0)->id : CODEC_ID_NONE; | ||||
|     ic->flags |= AVFMT_FLAG_NONBLOCK; | ||||
|     ic->interrupt_callback = int_cb; | ||||
|  | ||||
|     if (loop_input) { | ||||
|         av_log(NULL, AV_LOG_WARNING, "-loop_input is deprecated, use -loop 1\n"); | ||||
| @@ -3438,12 +3441,12 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV | ||||
|         if (codec_name) { | ||||
|             snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], | ||||
|                      i != 1 ? "" : "/.avconv", codec_name, preset_name); | ||||
|             ret = avio_open(s, filename, AVIO_FLAG_READ); | ||||
|             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); | ||||
|         } | ||||
|         if (ret) { | ||||
|             snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], | ||||
|                      i != 1 ? "" : "/.avconv", preset_name); | ||||
|             ret = avio_open(s, filename, AVIO_FLAG_READ); | ||||
|             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); | ||||
|         } | ||||
|     } | ||||
|     return ret; | ||||
| @@ -3856,8 +3859,9 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata) | ||||
| static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename) | ||||
| { | ||||
|     int i, err; | ||||
|     AVFormatContext *ic = NULL; | ||||
|     AVFormatContext *ic = avformat_alloc_context(); | ||||
|  | ||||
|     ic->interrupt_callback = int_cb; | ||||
|     err = avformat_open_input(&ic, filename, NULL, NULL); | ||||
|     if (err < 0) | ||||
|         return err; | ||||
| @@ -3908,6 +3912,7 @@ static void opt_output_file(void *optctx, const char *filename) | ||||
|         exit_program(1); | ||||
|     } | ||||
|     file_oformat= oc->oformat; | ||||
|     oc->interrupt_callback = int_cb; | ||||
|  | ||||
|     if (!strcmp(file_oformat->name, "ffm") && | ||||
|         av_strstart(filename, "http:", NULL)) { | ||||
| @@ -4019,7 +4024,7 @@ static void opt_output_file(void *optctx, const char *filename) | ||||
|         const char *p; | ||||
|         int64_t len; | ||||
|  | ||||
|         if ((err = avio_open(&pb, o->attachments[i], AVIO_FLAG_READ)) < 0) { | ||||
|         if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) { | ||||
|             av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n", | ||||
|                    o->attachments[i]); | ||||
|             exit_program(1); | ||||
| @@ -4069,7 +4074,9 @@ static void opt_output_file(void *optctx, const char *filename) | ||||
|         assert_file_overwrite(filename); | ||||
|  | ||||
|         /* open the file */ | ||||
|         if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { | ||||
|         if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, | ||||
|                               &oc->interrupt_callback, | ||||
|                               &output_files[nb_output_files - 1].opts)) < 0) { | ||||
|             print_error(filename, err); | ||||
|             exit_program(1); | ||||
|         } | ||||
| @@ -4725,12 +4732,6 @@ int main(int argc, char **argv) | ||||
|     av_register_all(); | ||||
|     avformat_network_init(); | ||||
|  | ||||
| #if HAVE_ISATTY | ||||
|     if(isatty(STDIN_FILENO)) | ||||
|         avio_set_interrupt_cb(decode_interrupt_cb); | ||||
| #endif | ||||
|  | ||||
|     show_banner(); | ||||
|  | ||||
|     term_init(); | ||||
|  | ||||
|   | ||||
							
								
								
									
										5
									
								
								ffplay.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								ffplay.c
									
									
									
									
									
								
							| @@ -2414,7 +2414,7 @@ static void stream_component_close(VideoState *is, int stream_index) | ||||
|    variable instead of a thread local variable */ | ||||
| static VideoState *global_video_state; | ||||
|  | ||||
| static int decode_interrupt_cb(void) | ||||
| static int decode_interrupt_cb(void *ctx) | ||||
| { | ||||
|     return (global_video_state && global_video_state->abort_request); | ||||
| } | ||||
| @@ -2439,8 +2439,9 @@ static int read_thread(void *arg) | ||||
|     is->subtitle_stream = -1; | ||||
|  | ||||
|     global_video_state = is; | ||||
|     avio_set_interrupt_cb(decode_interrupt_cb); | ||||
|  | ||||
|     ic = avformat_alloc_context(); | ||||
|     ic->interrupt_callback.callback = decode_interrupt_cb; | ||||
|     err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts); | ||||
|     if (err < 0) { | ||||
|         print_error(is->filename, err); | ||||
|   | ||||
| @@ -147,7 +147,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, | ||||
|         for (x=strip->x1; x < strip->x2; x+=4) { | ||||
|             if ((chunk_id & 0x01) && !(mask >>= 1)) { | ||||
|                 if ((data + 4) > eod) | ||||
|                     return -1; | ||||
|                     return AVERROR_INVALIDDATA; | ||||
|  | ||||
|                 flag  = AV_RB32 (data); | ||||
|                 data += 4; | ||||
| @@ -157,7 +157,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, | ||||
|             if (!(chunk_id & 0x01) || (flag & mask)) { | ||||
|                 if (!(chunk_id & 0x02) && !(mask >>= 1)) { | ||||
|                     if ((data + 4) > eod) | ||||
|                         return -1; | ||||
|                         return AVERROR_INVALIDDATA; | ||||
|  | ||||
|                     flag  = AV_RB32 (data); | ||||
|                     data += 4; | ||||
| @@ -166,7 +166,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, | ||||
|  | ||||
|                 if ((chunk_id & 0x02) || (~flag & mask)) { | ||||
|                     if (data >= eod) | ||||
|                         return -1; | ||||
|                         return AVERROR_INVALIDDATA; | ||||
|  | ||||
|                     codebook = &strip->v1_codebook[*data++]; | ||||
|                     s->frame.data[0][iy[0] + 0] = codebook->y0; | ||||
| @@ -207,7 +207,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, | ||||
|  | ||||
|                 } else if (flag & mask) { | ||||
|                     if ((data + 4) > eod) | ||||
|                         return -1; | ||||
|                         return AVERROR_INVALIDDATA; | ||||
|  | ||||
|                     codebook = &strip->v4_codebook[*data++]; | ||||
|                     s->frame.data[0][iy[0] + 0] = codebook->y0; | ||||
| @@ -272,13 +272,13 @@ static int cinepak_decode_strip (CinepakContext *s, | ||||
|     if (strip->x2 > s->width   || | ||||
|         strip->y2 > s->height  || | ||||
|         strip->x1 >= strip->x2 || strip->y1 >= strip->y2) | ||||
|         return -1; | ||||
|         return AVERROR_INVALIDDATA; | ||||
|  | ||||
|     while ((data + 4) <= eod) { | ||||
|         chunk_id   = data[0]; | ||||
|         chunk_size = AV_RB24 (&data[1]) - 4; | ||||
|         if(chunk_size < 0) | ||||
|             return -1; | ||||
|             return AVERROR_INVALIDDATA; | ||||
|  | ||||
|         data      += 4; | ||||
|         chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size; | ||||
| @@ -311,7 +311,7 @@ static int cinepak_decode_strip (CinepakContext *s, | ||||
|         data += chunk_size; | ||||
|     } | ||||
|  | ||||
|     return -1; | ||||
|     return AVERROR_INVALIDDATA; | ||||
| } | ||||
|  | ||||
| static int cinepak_decode (CinepakContext *s) | ||||
| @@ -322,7 +322,7 @@ static int cinepak_decode (CinepakContext *s) | ||||
|     int           encoded_buf_size; | ||||
|  | ||||
|     if (s->size < 10) | ||||
|         return -1; | ||||
|         return AVERROR_INVALIDDATA; | ||||
|  | ||||
|     frame_flags = s->data[0]; | ||||
|     num_strips  = AV_RB16 (&s->data[8]); | ||||
| @@ -330,9 +330,9 @@ static int cinepak_decode (CinepakContext *s) | ||||
|  | ||||
|     /* if this is the first frame, check for deviant Sega FILM data */ | ||||
|     if (s->sega_film_skip_bytes == -1) { | ||||
|         if (!encoded_buf_size){ | ||||
|         if (!encoded_buf_size) { | ||||
|             av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0"); | ||||
|             return -1; | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) { | ||||
|             /* If the encoded frame size differs from the frame size as indicated | ||||
| @@ -363,7 +363,7 @@ static int cinepak_decode (CinepakContext *s) | ||||
|  | ||||
|     for (i=0; i < num_strips; i++) { | ||||
|         if ((s->data + 12) > eod) | ||||
|             return -1; | ||||
|             return AVERROR_INVALIDDATA; | ||||
|  | ||||
|         s->strips[i].id = s->data[0]; | ||||
|         s->strips[i].y1 = y0; | ||||
| @@ -375,8 +375,8 @@ static int cinepak_decode (CinepakContext *s) | ||||
|             s->frame.key_frame = 1; | ||||
|  | ||||
|         strip_size = AV_RB24 (&s->data[1]) - 12; | ||||
|         if(strip_size < 0) | ||||
|             return -1; | ||||
|         if (strip_size < 0) | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         s->data   += 12; | ||||
|         strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size; | ||||
|  | ||||
| @@ -427,7 +427,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx, | ||||
|                                 AVPacket *avpkt) | ||||
| { | ||||
|     const uint8_t *buf = avpkt->data; | ||||
|     int buf_size = avpkt->size; | ||||
|     int ret = 0, buf_size = avpkt->size; | ||||
|     CinepakContext *s = avctx->priv_data; | ||||
|  | ||||
|     s->data = buf; | ||||
| @@ -436,9 +436,9 @@ static int cinepak_decode_frame(AVCodecContext *avctx, | ||||
|     s->frame.reference = 3; | ||||
|     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | | ||||
|                             FF_BUFFER_HINTS_REUSABLE; | ||||
|     if (avctx->reget_buffer(avctx, &s->frame)) { | ||||
|     if ((ret = avctx->reget_buffer(avctx, &s->frame))) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); | ||||
|         return -1; | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
|     if (s->palette_video) { | ||||
|   | ||||
| @@ -259,6 +259,7 @@ void av_register_all(void) | ||||
|     REGISTER_PROTOCOL (FILE, file); | ||||
|     REGISTER_PROTOCOL (GOPHER, gopher); | ||||
|     REGISTER_PROTOCOL (HTTP, http); | ||||
|     REGISTER_PROTOCOL (HTTPPROXY, httpproxy); | ||||
|     REGISTER_PROTOCOL (HTTPS, https); | ||||
|     REGISTER_PROTOCOL (MMSH, mmsh); | ||||
|     REGISTER_PROTOCOL (MMST, mmst); | ||||
|   | ||||
| @@ -644,7 +644,8 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index, | ||||
|     for (i = 0; i < c->n_variants; i++) { | ||||
|         /* Reset reading */ | ||||
|         struct variant *var = c->variants[i]; | ||||
|         int64_t pos = av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ? | ||||
|         int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 : | ||||
|                       av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ? | ||||
|                                s->streams[stream_index]->time_base.den : | ||||
|                                AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ? | ||||
|                                AV_ROUND_DOWN : AV_ROUND_UP); | ||||
|   | ||||
| @@ -83,9 +83,11 @@ const AVClass ffurl_context_class = { | ||||
| }; | ||||
| /*@}*/ | ||||
|  | ||||
| static int default_interrupt_cb(void); | ||||
|  | ||||
| #if FF_API_OLD_INTERRUPT_CB | ||||
| static int default_interrupt_cb(void); | ||||
| int (*url_interrupt_cb)(void) = default_interrupt_cb; | ||||
| #endif | ||||
|  | ||||
| URLProtocol *av_protocol_next(URLProtocol *p) | ||||
| { | ||||
| @@ -444,6 +446,7 @@ int ffurl_get_file_handle(URLContext *h) | ||||
|     return h->prot->url_get_file_handle(h); | ||||
| } | ||||
|  | ||||
| #if FF_API_OLD_INTERRUPT_CB | ||||
| static int default_interrupt_cb(void) | ||||
| { | ||||
|     return 0; | ||||
| @@ -455,13 +458,18 @@ void avio_set_interrupt_cb(int (*interrupt_cb)(void)) | ||||
|         interrupt_cb = default_interrupt_cb; | ||||
|     url_interrupt_cb = interrupt_cb; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| int ff_check_interrupt(AVIOInterruptCB *cb) | ||||
| { | ||||
|     int ret; | ||||
|     if (cb && cb->callback && (ret = cb->callback(cb->opaque))) | ||||
|         return ret; | ||||
| #if FF_API_OLD_INTERRUPT_CB | ||||
|     return url_interrupt_cb(); | ||||
| #else | ||||
|     return 0; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #if FF_API_OLD_AVIO | ||||
|   | ||||
| @@ -386,13 +386,17 @@ attribute_deprecated int url_exist(const char *url); | ||||
|  */ | ||||
| int avio_check(const char *url, int flags); | ||||
|  | ||||
| #if FF_API_OLD_INTERRUPT_CB | ||||
| /** | ||||
|  * The callback is called in blocking functions to test regulary if | ||||
|  * asynchronous interruption is needed. AVERROR_EXIT is returned | ||||
|  * in this case by the interrupted function. 'NULL' means no interrupt | ||||
|  * callback is given. | ||||
|  * @deprecated Use interrupt_callback in AVFormatContext/avio_open2 | ||||
|  *             instead. | ||||
|  */ | ||||
| void avio_set_interrupt_cb(int (*interrupt_cb)(void)); | ||||
| attribute_deprecated void avio_set_interrupt_cb(int (*interrupt_cb)(void)); | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Allocate and initialize an AVIOContext for buffered I/O. It must be later | ||||
|   | ||||
| @@ -110,6 +110,15 @@ static int http_open_cnx(URLContext *h) | ||||
|                  path1, sizeof(path1), s->location); | ||||
|     ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); | ||||
|  | ||||
|     if (!strcmp(proto, "https")) { | ||||
|         lower_proto = "tls"; | ||||
|         use_proxy = 0; | ||||
|         if (port < 0) | ||||
|             port = 443; | ||||
|     } | ||||
|     if (port < 0) | ||||
|         port = 80; | ||||
|  | ||||
|     if (path1[0] == '\0') | ||||
|         path = "/"; | ||||
|     else | ||||
| @@ -124,13 +133,6 @@ static int http_open_cnx(URLContext *h) | ||||
|         av_url_split(NULL, 0, proxyauth, sizeof(proxyauth), | ||||
|                      hostname, sizeof(hostname), &port, NULL, 0, proxy_path); | ||||
|     } | ||||
|     if (!strcmp(proto, "https")) { | ||||
|         lower_proto = "tls"; | ||||
|         if (port < 0) | ||||
|             port = 443; | ||||
|     } | ||||
|     if (port < 0) | ||||
|         port = 80; | ||||
|  | ||||
|     ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL); | ||||
|     err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE, | ||||
| @@ -413,10 +415,33 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, | ||||
| } | ||||
|  | ||||
|  | ||||
| static int http_read(URLContext *h, uint8_t *buf, int size) | ||||
| static int http_buf_read(URLContext *h, uint8_t *buf, int size) | ||||
| { | ||||
|     HTTPContext *s = h->priv_data; | ||||
|     int len; | ||||
|     /* read bytes from input buffer first */ | ||||
|     len = s->buf_end - s->buf_ptr; | ||||
|     if (len > 0) { | ||||
|         if (len > size) | ||||
|             len = size; | ||||
|         memcpy(buf, s->buf_ptr, len); | ||||
|         s->buf_ptr += len; | ||||
|     } else { | ||||
|         if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize) | ||||
|             return AVERROR_EOF; | ||||
|         len = ffurl_read(s->hd, buf, size); | ||||
|     } | ||||
|     if (len > 0) { | ||||
|         s->off += len; | ||||
|         if (s->chunksize > 0) | ||||
|             s->chunksize -= len; | ||||
|     } | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| static int http_read(URLContext *h, uint8_t *buf, int size) | ||||
| { | ||||
|     HTTPContext *s = h->priv_data; | ||||
|  | ||||
|     if (s->chunksize >= 0) { | ||||
|         if (!s->chunksize) { | ||||
| @@ -439,24 +464,7 @@ static int http_read(URLContext *h, uint8_t *buf, int size) | ||||
|         } | ||||
|         size = FFMIN(size, s->chunksize); | ||||
|     } | ||||
|     /* read bytes from input buffer first */ | ||||
|     len = s->buf_end - s->buf_ptr; | ||||
|     if (len > 0) { | ||||
|         if (len > size) | ||||
|             len = size; | ||||
|         memcpy(buf, s->buf_ptr, len); | ||||
|         s->buf_ptr += len; | ||||
|     } else { | ||||
|         if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize) | ||||
|             return AVERROR_EOF; | ||||
|         len = ffurl_read(s->hd, buf, size); | ||||
|     } | ||||
|     if (len > 0) { | ||||
|         s->off += len; | ||||
|         if (s->chunksize > 0) | ||||
|             s->chunksize -= len; | ||||
|     } | ||||
|     return len; | ||||
|     return http_buf_read(h, buf, size); | ||||
| } | ||||
|  | ||||
| /* used only when posting data */ | ||||
| @@ -572,3 +580,118 @@ URLProtocol ff_https_protocol = { | ||||
|     .priv_data_class     = &https_context_class, | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if CONFIG_HTTPPROXY_PROTOCOL | ||||
| static int http_proxy_close(URLContext *h) | ||||
| { | ||||
|     HTTPContext *s = h->priv_data; | ||||
|     if (s->hd) | ||||
|         ffurl_close(s->hd); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int http_proxy_open(URLContext *h, const char *uri, int flags) | ||||
| { | ||||
|     HTTPContext *s = h->priv_data; | ||||
|     char hostname[1024], hoststr[1024]; | ||||
|     char auth[1024], pathbuf[1024], *path; | ||||
|     char line[1024], lower_url[100]; | ||||
|     int port, ret = 0; | ||||
|     HTTPAuthType cur_auth_type; | ||||
|     char *authstr; | ||||
|  | ||||
|     h->is_streamed = 1; | ||||
|  | ||||
|     av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, | ||||
|                  pathbuf, sizeof(pathbuf), uri); | ||||
|     ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); | ||||
|     path = pathbuf; | ||||
|     if (*path == '/') | ||||
|         path++; | ||||
|  | ||||
|     ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port, | ||||
|                 NULL); | ||||
| redo: | ||||
|     ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, | ||||
|                      &h->interrupt_callback, NULL); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth, | ||||
|                                            path, "CONNECT"); | ||||
|     snprintf(s->buffer, sizeof(s->buffer), | ||||
|              "CONNECT %s HTTP/1.1\r\n" | ||||
|              "Host: %s\r\n" | ||||
|              "Connection: close\r\n" | ||||
|              "%s%s" | ||||
|              "\r\n", | ||||
|              path, | ||||
|              hoststr, | ||||
|              authstr ? "Proxy-" : "", authstr ? authstr : ""); | ||||
|     av_freep(&authstr); | ||||
|  | ||||
|     if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0) | ||||
|         goto fail; | ||||
|  | ||||
|     s->buf_ptr = s->buffer; | ||||
|     s->buf_end = s->buffer; | ||||
|     s->line_count = 0; | ||||
|     s->filesize = -1; | ||||
|     cur_auth_type = s->proxy_auth_state.auth_type; | ||||
|  | ||||
|     for (;;) { | ||||
|         int new_loc; | ||||
|         // Note: This uses buffering, potentially reading more than the | ||||
|         // HTTP header. If tunneling a protocol where the server starts | ||||
|         // the conversation, we might buffer part of that here, too. | ||||
|         // Reading that requires using the proper ffurl_read() function | ||||
|         // on this URLContext, not using the fd directly (as the tls | ||||
|         // protocol does). This shouldn't be an issue for tls though, | ||||
|         // since the client starts the conversation there, so there | ||||
|         // is no extra data that we might buffer up here. | ||||
|         if (http_get_line(s, line, sizeof(line)) < 0) { | ||||
|             ret = AVERROR(EIO); | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         av_dlog(h, "header='%s'\n", line); | ||||
|  | ||||
|         ret = process_line(h, line, s->line_count, &new_loc); | ||||
|         if (ret < 0) | ||||
|             goto fail; | ||||
|         if (ret == 0) | ||||
|             break; | ||||
|         s->line_count++; | ||||
|     } | ||||
|     if (s->http_code == 407 && cur_auth_type == HTTP_AUTH_NONE && | ||||
|         s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) { | ||||
|         ffurl_close(s->hd); | ||||
|         s->hd = NULL; | ||||
|         goto redo; | ||||
|     } | ||||
|  | ||||
|     if (s->http_code < 400) | ||||
|         return 0; | ||||
|     ret = AVERROR(EIO); | ||||
|  | ||||
| fail: | ||||
|     http_proxy_close(h); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static int http_proxy_write(URLContext *h, const uint8_t *buf, int size) | ||||
| { | ||||
|     HTTPContext *s = h->priv_data; | ||||
|     return ffurl_write(s->hd, buf, size); | ||||
| } | ||||
|  | ||||
| URLProtocol ff_httpproxy_protocol = { | ||||
|     .name                = "httpproxy", | ||||
|     .url_open            = http_proxy_open, | ||||
|     .url_read            = http_buf_read, | ||||
|     .url_write           = http_proxy_write, | ||||
|     .url_close           = http_proxy_close, | ||||
|     .url_get_file_handle = http_get_file_handle, | ||||
|     .priv_data_size      = sizeof(HTTPContext), | ||||
| }; | ||||
| #endif | ||||
|   | ||||
| @@ -74,6 +74,7 @@ typedef struct RTMPContext { | ||||
|     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call | ||||
|     uint8_t       flv_header[11];             ///< partial incoming flv packet header | ||||
|     int           flv_header_bytes;           ///< number of initialized bytes in flv_header | ||||
|     int           nb_invokes;                 ///< keeps track of invoke messages | ||||
| } RTMPContext; | ||||
|  | ||||
| #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing | ||||
| @@ -166,7 +167,7 @@ static void gen_release_stream(URLContext *s, RTMPContext *rt) | ||||
|     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n"); | ||||
|     p = pkt.data; | ||||
|     ff_amf_write_string(&p, "releaseStream"); | ||||
|     ff_amf_write_number(&p, 2.0); | ||||
|     ff_amf_write_number(&p, ++rt->nb_invokes); | ||||
|     ff_amf_write_null(&p); | ||||
|     ff_amf_write_string(&p, rt->playpath); | ||||
|  | ||||
| @@ -189,7 +190,7 @@ static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt) | ||||
|     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n"); | ||||
|     p = pkt.data; | ||||
|     ff_amf_write_string(&p, "FCPublish"); | ||||
|     ff_amf_write_number(&p, 3.0); | ||||
|     ff_amf_write_number(&p, ++rt->nb_invokes); | ||||
|     ff_amf_write_null(&p); | ||||
|     ff_amf_write_string(&p, rt->playpath); | ||||
|  | ||||
| @@ -212,7 +213,7 @@ static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt) | ||||
|     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n"); | ||||
|     p = pkt.data; | ||||
|     ff_amf_write_string(&p, "FCUnpublish"); | ||||
|     ff_amf_write_number(&p, 5.0); | ||||
|     ff_amf_write_number(&p, ++rt->nb_invokes); | ||||
|     ff_amf_write_null(&p); | ||||
|     ff_amf_write_string(&p, rt->playpath); | ||||
|  | ||||
| @@ -234,7 +235,7 @@ static void gen_create_stream(URLContext *s, RTMPContext *rt) | ||||
|  | ||||
|     p = pkt.data; | ||||
|     ff_amf_write_string(&p, "createStream"); | ||||
|     ff_amf_write_number(&p, rt->is_input ? 3.0 : 4.0); | ||||
|     ff_amf_write_number(&p, ++rt->nb_invokes); | ||||
|     ff_amf_write_null(&p); | ||||
|  | ||||
|     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); | ||||
|   | ||||
| @@ -429,7 +429,7 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam | ||||
|     if (timestamp == RTP_NOTS_VALUE) | ||||
|         return; | ||||
|  | ||||
|     if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { | ||||
|     if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && s->ic->nb_streams > 1) { | ||||
|         int64_t addend; | ||||
|         int delta_timestamp; | ||||
|  | ||||
| @@ -444,7 +444,13 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam | ||||
|  | ||||
|     if (!s->base_timestamp) | ||||
|         s->base_timestamp = timestamp; | ||||
|     pkt->pts = s->range_start_offset + timestamp - s->base_timestamp; | ||||
|     /* assume that the difference is INT32_MIN < x < INT32_MAX, but allow the first timestamp to exceed INT32_MAX */ | ||||
|     if (!s->timestamp) | ||||
|         s->unwrapped_timestamp += timestamp; | ||||
|     else | ||||
|         s->unwrapped_timestamp += (int32_t)(timestamp - s->timestamp); | ||||
|     s->timestamp = timestamp; | ||||
|     pkt->pts = s->unwrapped_timestamp + s->range_start_offset - s->base_timestamp; | ||||
| } | ||||
|  | ||||
| static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt, | ||||
|   | ||||
| @@ -151,6 +151,7 @@ struct RTPDemuxContext { | ||||
|     uint32_t timestamp; | ||||
|     uint32_t base_timestamp; | ||||
|     uint32_t cur_timestamp; | ||||
|     int64_t  unwrapped_timestamp; | ||||
|     int64_t  range_start_offset; | ||||
|     int max_payload_size; | ||||
|     struct MpegTSContext *ts;   /* only used for MP2T payloads */ | ||||
|   | ||||
| @@ -52,6 +52,8 @@ static int rtsp_read_play(AVFormatContext *s) | ||||
|                 rtpctx->last_rtcp_ntp_time  = AV_NOPTS_VALUE; | ||||
|                 rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE; | ||||
|                 rtpctx->base_timestamp      = 0; | ||||
|                 rtpctx->timestamp           = 0; | ||||
|                 rtpctx->unwrapped_timestamp = 0; | ||||
|                 rtpctx->rtcp_ts_offset      = 0; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -34,6 +34,7 @@ | ||||
| #define FDSC_TAG MKBETAG('F', 'D', 'S', 'C') | ||||
| #define STAB_TAG MKBETAG('S', 'T', 'A', 'B') | ||||
| #define CVID_TAG MKBETAG('c', 'v', 'i', 'd') | ||||
| #define RAW_TAG  MKBETAG('r', 'a', 'w', ' ') | ||||
|  | ||||
| typedef struct { | ||||
|   int stream; | ||||
| @@ -129,8 +130,11 @@ static int film_read_header(AVFormatContext *s, | ||||
|  | ||||
|     if (AV_RB32(&scratch[8]) == CVID_TAG) { | ||||
|         film->video_type = CODEC_ID_CINEPAK; | ||||
|     } else | ||||
|     } else if (AV_RB32(&scratch[8]) == RAW_TAG) { | ||||
|         film->video_type = CODEC_ID_RAWVIDEO; | ||||
|     } else { | ||||
|         film->video_type = CODEC_ID_NONE; | ||||
|     } | ||||
|  | ||||
|     /* initialize the decoder streams */ | ||||
|     if (film->video_type) { | ||||
| @@ -143,6 +147,15 @@ static int film_read_header(AVFormatContext *s, | ||||
|         st->codec->codec_tag = 0;  /* no fourcc */ | ||||
|         st->codec->width = AV_RB32(&scratch[16]); | ||||
|         st->codec->height = AV_RB32(&scratch[12]); | ||||
|  | ||||
|         if (film->video_type == CODEC_ID_RAWVIDEO) { | ||||
|             if (scratch[20] == 24) { | ||||
|                 st->codec->pix_fmt = PIX_FMT_RGB24; | ||||
|             } else { | ||||
|                 av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]); | ||||
|                 return -1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (film->audio_type) { | ||||
|   | ||||
| @@ -111,9 +111,15 @@ static int tls_open(URLContext *h, const char *uri, int flags) | ||||
|     char buf[200], host[200]; | ||||
|     int numerichost = 0; | ||||
|     struct addrinfo hints = { 0 }, *ai = NULL; | ||||
|     const char *proxy_path; | ||||
|     int use_proxy; | ||||
|  | ||||
|     ff_tls_init(); | ||||
|  | ||||
|     proxy_path = getenv("http_proxy"); | ||||
|     use_proxy = (proxy_path != NULL) && !getenv("no_proxy") && | ||||
|         av_strstart(proxy_path, "http://", NULL); | ||||
|  | ||||
|     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri); | ||||
|     ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, NULL); | ||||
|  | ||||
| @@ -123,6 +129,17 @@ static int tls_open(URLContext *h, const char *uri, int flags) | ||||
|         freeaddrinfo(ai); | ||||
|     } | ||||
|  | ||||
|     if (use_proxy) { | ||||
|         char proxy_host[200], proxy_auth[200], dest[200]; | ||||
|         int proxy_port; | ||||
|         av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth), | ||||
|                      proxy_host, sizeof(proxy_host), &proxy_port, NULL, 0, | ||||
|                      proxy_path); | ||||
|         ff_url_join(dest, sizeof(dest), NULL, NULL, host, port, NULL); | ||||
|         ff_url_join(buf, sizeof(buf), "httpproxy", proxy_auth, proxy_host, | ||||
|                     proxy_port, "/%s", dest); | ||||
|     } | ||||
|  | ||||
|     ret = ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE, | ||||
|                      &h->interrupt_callback, NULL); | ||||
|     if (ret) | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| #include "libavutil/avutil.h" | ||||
|  | ||||
| #define LIBAVFORMAT_VERSION_MAJOR 53 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 20 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 21 | ||||
| #define LIBAVFORMAT_VERSION_MICRO  0 | ||||
|  | ||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
| @@ -113,5 +113,8 @@ | ||||
| #ifndef FF_API_REORDER_PRIVATE | ||||
| #define FF_API_REORDER_PRIVATE         (LIBAVFORMAT_VERSION_MAJOR < 54) | ||||
| #endif | ||||
| #ifndef FF_API_OLD_INTERRUPT_CB | ||||
| #define FF_API_OLD_INTERRUPT_CB        (LIBAVFORMAT_VERSION_MAJOR < 54) | ||||
| #endif | ||||
|  | ||||
| #endif /* AVFORMAT_VERSION_H */ | ||||
|   | ||||
| @@ -71,7 +71,7 @@ do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec m | ||||
| fi | ||||
|  | ||||
| if [ -n "$do_ts" ] ; then | ||||
| do_lavf ts "-ab 64k" | ||||
| do_lavf ts "-ab 64k -mpegts_transport_stream_id 42" | ||||
| fi | ||||
|  | ||||
| if [ -n "$do_swf" ] ; then | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| 151774afed45b19da9b7e83613a1e72b *./tests/data/lavf/lavf.ts | ||||
| 024f0cdd4c51a158b2a38b901d2ed2e5 *./tests/data/lavf/lavf.ts | ||||
| 406644 ./tests/data/lavf/lavf.ts | ||||
| ./tests/data/lavf/lavf.ts CRC=0x133216c1 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Niedermayer
					Michael Niedermayer