See doc/multithreading.txt for details on use in codecs.
Unified · Split
| @@ -13,6 +13,11 @@ libavutil: 2009-03-08 · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | API changes, most recent first: | 14 | API changes, most recent first: |
| 15 | 15 | ||
| 16 | 2011-02-09 - XXXXXXX - lavc 52.111.0 - threading API | ||
| 17 | Add CODEC_CAP_FRAME_THREADS with new restrictions on get_buffer()/ | ||
| 18 | release_buffer()/draw_horiz_band() callbacks for appropriate codecs. | ||
| 19 | Add thread_type and active_thread_type fields to AVCodecContext. | ||
| 20 | |||
| 16 | 2011-02-08 - 3940caa - lavf 52.98.0 - av_probe_input_buffer | 21 | 2011-02-08 - 3940caa - lavf 52.98.0 - av_probe_input_buffer |
| 17 | Add av_probe_input_buffer() to avformat.h for probing format from a | 22 | Add av_probe_input_buffer() to avformat.h for probing format from a |
| 18 | ByteIOContext. | 23 | ByteIOContext. |
| @@ -0,0 +1,65 @@ | |||
| 1 | FFmpeg multithreading methods | ||
| 2 | ============================================== | ||
| 3 | |||
| 4 | FFmpeg provides two methods for multithreading codecs. | ||
| 5 | |||
| 6 | Slice threading decodes multiple parts of a frame at the same time, using | ||
| 7 | AVCodecContext execute() and execute2(). | ||
| 8 | |||
| 9 | Frame threading decodes multiple frames at the same time. | ||
| 10 | It accepts N future frames and delays decoded pictures by N-1 frames. | ||
| 11 | The later frames are decoded in separate threads while the user is | ||
| 12 | displaying the current one. | ||
| 13 | |||
| 14 | Restrictions on clients | ||
| 15 | ============================================== | ||
| 16 | |||
| 17 | Slice threading - | ||
| 18 | * The client's draw_horiz_band() must be thread-safe according to the comment | ||
| 19 | in avcodec.h. | ||
| 20 | |||
| 21 | Frame threading - | ||
| 22 | * Restrictions with slice threading also apply. | ||
| 23 | * For best performance, the client should set thread_safe_callbacks if it | ||
| 24 | provides a thread-safe get_buffer() callback. | ||
| 25 | * There is one frame of delay added for every thread beyond the first one. | ||
| 26 | Clients must be able to handle this; the pkt_dts and pkt_pts fields in | ||
| 27 | AVFrame will work as usual. | ||
| 28 | |||
| 29 | Restrictions on codec implementations | ||
| 30 | ============================================== | ||
| 31 | |||
| 32 | Slice threading - | ||
| 33 | None except that there must be something worth executing in parallel. | ||
| 34 | |||
| 35 | Frame threading - | ||
| 36 | * Codecs can only accept entire pictures per packet. | ||
| 37 | * Codecs similar to ffv1, whose streams don't reset across frames, | ||
| 38 | will not work because their bitstreams cannot be decoded in parallel. | ||
| 39 | |||
| 40 | * The contents of buffers must not be read before ff_thread_await_progress() | ||
| 41 | has been called on them. reget_buffer() and buffer age optimizations no longer work. | ||
| 42 | * The contents of buffers must not be written to after ff_thread_report_progress() | ||
| 43 | has been called on them. This includes draw_edges(). | ||
| 44 | |||
| 45 | Porting codecs to frame threading | ||
| 46 | ============================================== | ||
| 47 | |||
| 48 | Find all context variables that are needed by the next frame. Move all | ||
| 49 | code changing them, as well as code calling get_buffer(), up to before | ||
| 50 | the decode process starts. Call ff_thread_finish_setup() afterwards. If | ||
| 51 | some code can't be moved, have update_thread_context() run it in the next | ||
| 52 | thread. | ||
| 53 | |||
| 54 | If the codec allocates writable tables in its init(), add an init_thread_copy() | ||
| 55 | which re-allocates them for other threads. | ||
| 56 | |||
| 57 | Add CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little | ||
| 58 | speed gain at this point but it should work. | ||
| 59 | |||
| 60 | Call ff_thread_report_progress() after some part of the current picture has decoded. | ||
| 61 | A good place to put this is where draw_horiz_band() is called - add this if it isn't | ||
| 62 | called anywhere, as it's useful too and the implementation is trivial when you're | ||
| 63 | doing this. Note that draw_edges() needs to be called before reporting progress. | ||
| 64 | |||
| 65 | Before accessing a reference frame or its MVs, call ff_thread_await_progress(). | ||
| @@ -1691,6 +1691,7 @@ static int input_init(AVFilterContext *ctx, const char *args, void *opaque) · 1690 unmodified lines | |||
| 1691 | codec->get_buffer = input_get_buffer; | 1691 | codec->get_buffer = input_get_buffer; |
| 1692 | codec->release_buffer = input_release_buffer; | 1692 | codec->release_buffer = input_release_buffer; |
| 1693 | codec->reget_buffer = input_reget_buffer; | 1693 | codec->reget_buffer = input_reget_buffer; |
| 1694 | codec->thread_safe_callbacks = 1; | ||
| 1694 | } | 1695 | } |
| 1695 | 1696 | ||
| 1696 | priv->frame = avcodec_alloc_frame(); | 1697 | priv->frame = avcodec_alloc_frame(); |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include "libavutil/cpu.h" | 32 | #include "libavutil/cpu.h" |
| 33 | 33 | ||
| 34 | #define LIBAVCODEC_VERSION_MAJOR 52 | 34 | #define LIBAVCODEC_VERSION_MAJOR 52 |
| 35 | #define LIBAVCODEC_VERSION_MINOR 110 | 35 | #define LIBAVCODEC_VERSION_MINOR 111 |
| 36 | #define LIBAVCODEC_VERSION_MICRO 0 | 36 | #define LIBAVCODEC_VERSION_MICRO 0 |
| 37 | 37 | ||
| 38 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | 38 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |
| @@ -728,6 +728,10 @@ typedef struct RcOverride{ · 689 unmodified lines | |||
| 728 | * Codec is able to deal with negative linesizes | 728 | * Codec is able to deal with negative linesizes |
| 729 | */ | 729 | */ |
| 730 | #define CODEC_CAP_NEG_LINESIZES 0x0800 | 730 | #define CODEC_CAP_NEG_LINESIZES 0x0800 |
| 731 | /** | ||
| 732 | * Codec supports frame-level multithreading. | ||
| 733 | */ | ||
| 734 | #define CODEC_CAP_FRAME_THREADS 0x1000 | ||
| 731 | 735 | ||
| 732 | //The following defines may change, don't expect compatibility if you use them. | 736 | //The following defines may change, don't expect compatibility if you use them. |
| 733 | #define MB_TYPE_INTRA4x4 0x0001 | 737 | #define MB_TYPE_INTRA4x4 0x0001 |
| @@ -1027,6 +1031,20 @@ typedef struct AVPanScan{ · 293 unmodified lines | |||
| 1027 | * - decoding: Read by user.\ | 1031 | * - decoding: Read by user.\ |
| 1028 | */\ | 1032 | */\ |
| 1029 | int64_t pkt_dts;\ | 1033 | int64_t pkt_dts;\ |
| 1034 | \ | ||
| 1035 | /**\ | ||
| 1036 | * the AVCodecContext which ff_thread_get_buffer() was last called on\ | ||
| 1037 | * - encoding: Set by libavcodec.\ | ||
| 1038 | * - decoding: Set by libavcodec.\ | ||
| 1039 | */\ | ||
| 1040 | struct AVCodecContext *owner;\ | ||
| 1041 | \ | ||
| 1042 | /**\ | ||
| 1043 | * used by multithreading to store frame-specific info\ | ||
| 1044 | * - encoding: Set by libavcodec.\ | ||
| 1045 | * - decoding: Set by libavcodec.\ | ||
| 1046 | */\ | ||
| 1047 | void *thread_opaque;\ | ||
| 1030 | \ | 1048 | \ |
| 1031 | /**\ | 1049 | /**\ |
| 1032 | * frame timestamp estimated using various heuristics, in stream time base\ | 1050 | * frame timestamp estimated using various heuristics, in stream time base\ |
| @@ -1246,6 +1264,10 @@ typedef struct AVCodecContext { · 213 unmodified lines | |||
| 1246 | * decoder to draw a horizontal band. It improves cache usage. Not | 1264 | * decoder to draw a horizontal band. It improves cache usage. Not |
| 1247 | * all codecs can do that. You must check the codec capabilities | 1265 | * all codecs can do that. You must check the codec capabilities |
| 1248 | * beforehand. | 1266 | * beforehand. |
| 1267 | * When multithreading is used, it may be called from multiple threads | ||
| 1268 | * at the same time; threads might draw different parts of the same AVFrame, | ||
| 1269 | * or multiple AVFrames, and there is no guarantee that slices will be drawn | ||
| 1270 | * in order. | ||
| 1249 | * The function is also used by hardware acceleration APIs. | 1271 | * The function is also used by hardware acceleration APIs. |
| 1250 | * It is called at least once during frame decoding to pass | 1272 | * It is called at least once during frame decoding to pass |
| 1251 | * the data needed for hardware render. | 1273 | * the data needed for hardware render. |
| @@ -1499,6 +1521,9 @@ typedef struct AVCodecContext { · 247 unmodified lines | |||
| 1499 | * if CODEC_CAP_DR1 is not set then get_buffer() must call | 1521 | * if CODEC_CAP_DR1 is not set then get_buffer() must call |
| 1500 | * avcodec_default_get_buffer() instead of providing buffers allocated by | 1522 | * avcodec_default_get_buffer() instead of providing buffers allocated by |
| 1501 | * some other means. | 1523 | * some other means. |
| 1524 | * If frame multithreading is used and thread_safe_callbacks is set, | ||
| 1525 | * it may be called from a different thread, but not from more than one at once. | ||
| 1526 | * Does not need to be reentrant. | ||
| 1502 | * - encoding: unused | 1527 | * - encoding: unused |
| 1503 | * - decoding: Set by libavcodec, user can override. | 1528 | * - decoding: Set by libavcodec, user can override. |
| 1504 | */ | 1529 | */ |
| @@ -1508,6 +1533,8 @@ typedef struct AVCodecContext { · 3 unmodified lines | |||
| 1508 | * Called to release buffers which were allocated with get_buffer. | 1533 | * Called to release buffers which were allocated with get_buffer. |
| 1509 | * A released buffer can be reused in get_buffer(). | 1534 | * A released buffer can be reused in get_buffer(). |
| 1510 | * pic.data[*] must be set to NULL. | 1535 | * pic.data[*] must be set to NULL. |
| 1536 | * May be called from a different thread if frame multithreading is used, | ||
| 1537 | * but not by more than one thread at once, so does not need to be reentrant. | ||
| 1511 | * - encoding: unused | 1538 | * - encoding: unused |
| 1512 | * - decoding: Set by libavcodec, user can override. | 1539 | * - decoding: Set by libavcodec, user can override. |
| 1513 | */ | 1540 | */ |
| @@ -1811,6 +1838,7 @@ typedef struct AVCodecContext { · 297 unmodified lines | |||
| 1811 | #define FF_DEBUG_VIS_QP 0x00002000 | 1838 | #define FF_DEBUG_VIS_QP 0x00002000 |
| 1812 | #define FF_DEBUG_VIS_MB_TYPE 0x00004000 | 1839 | #define FF_DEBUG_VIS_MB_TYPE 0x00004000 |
| 1813 | #define FF_DEBUG_BUFFERS 0x00008000 | 1840 | #define FF_DEBUG_BUFFERS 0x00008000 |
| 1841 | #define FF_DEBUG_THREADS 0x00010000 | ||
| 1814 | 1842 | ||
| 1815 | /** | 1843 | /** |
| 1816 | * debug | 1844 | * debug |
| @@ -2835,6 +2863,44 @@ typedef struct AVCodecContext { · 1018 unmodified lines | |||
| 2835 | */ | 2863 | */ |
| 2836 | AVPacket *pkt; | 2864 | AVPacket *pkt; |
| 2837 | 2865 | ||
| 2866 | /** | ||
| 2867 | * Whether this is a copy of the context which had init() called on it. | ||
| 2868 | * This is used by multithreading - shared tables and picture pointers | ||
| 2869 | * should be freed from the original context only. | ||
| 2870 | * - encoding: Set by libavcodec. | ||
| 2871 | * - decoding: Set by libavcodec. | ||
| 2872 | */ | ||
| 2873 | int is_copy; | ||
| 2874 | |||
| 2875 | /** | ||
| 2876 | * Which multithreading methods to use. | ||
| 2877 | * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread, | ||
| 2878 | * so clients which cannot provide future frames should not use it. | ||
| 2879 | * | ||
| 2880 | * - encoding: Set by user, otherwise the default is used. | ||
| 2881 | * - decoding: Set by user, otherwise the default is used. | ||
| 2882 | */ | ||
| 2883 | int thread_type; | ||
| 2884 | #define FF_THREAD_FRAME 1 //< Decode more than one frame at once | ||
| 2885 | #define FF_THREAD_SLICE 2 //< Decode more than one part of a single frame at once | ||
| 2886 | |||
| 2887 | /** | ||
| 2888 | * Which multithreading methods are in use by the codec. | ||
| 2889 | * - encoding: Set by libavcodec. | ||
| 2890 | * - decoding: Set by libavcodec. | ||
| 2891 | */ | ||
| 2892 | int active_thread_type; | ||
| 2893 | |||
| 2894 | /** | ||
| 2895 | * Set by the client if its custom get_buffer() callback can be called | ||
| 2896 | * from another thread, which allows faster multithreaded decoding. | ||
| 2897 | * draw_horiz_band() will be called from other threads regardless of this setting. | ||
| 2898 | * Ignored if the default get_buffer() is used. | ||
| 2899 | * - encoding: Set by user. | ||
| 2900 | * - decoding: Set by user. | ||
| 2901 | */ | ||
| 2902 | int thread_safe_callbacks; | ||
| 2903 | |||
| 2838 | /** | 2904 | /** |
| 2839 | * Current statistics for PTS correction. | 2905 | * Current statistics for PTS correction. |
| 2840 | * - decoding: maintained and used by libavcodec | 2906 | * - decoding: maintained and used by libavcodec |
| @@ -2897,6 +2963,26 @@ typedef struct AVCodec { · 56 unmodified lines | |||
| 2897 | uint8_t max_lowres; ///< maximum value for lowres supported by the decoder | 2963 | uint8_t max_lowres; ///< maximum value for lowres supported by the decoder |
| 2898 | AVClass *priv_class; ///< AVClass for the private context | 2964 | AVClass *priv_class; ///< AVClass for the private context |
| 2899 | const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} | 2965 | const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} |
| 2966 | |||
| 2967 | /** | ||
| 2968 | * @defgroup framethreading Frame-level threading support functions. | ||
| 2969 | * @{ | ||
| 2970 | */ | ||
| 2971 | /** | ||
| 2972 | * If defined, called on thread contexts when they are created. | ||
| 2973 | * If the codec allocates writable tables in init(), re-allocate them here. | ||
| 2974 | * priv_data will be set to a copy of the original. | ||
| 2975 | */ | ||
| 2976 | int (*init_thread_copy)(AVCodecContext *); | ||
| 2977 | /** | ||
| 2978 | * Copy necessary context variables from a previous thread context to the current one. | ||
| 2979 | * If not defined, the next thread will start automatically; otherwise, the codec | ||
| 2980 | * must call ff_thread_finish_setup(). | ||
| 2981 | * | ||
| 2982 | * dst and src will (rarely) point to the same context, in which case memcpy should be skipped. | ||
| 2983 | */ | ||
| 2984 | int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src); | ||
| 2985 | /** @} */ | ||
| 2900 | } AVCodec; | 2986 | } AVCodec; |
| 2901 | 2987 | ||
| 2902 | /** | 2988 | /** |
| @@ -250,6 +250,7 @@ static const AVOption options[]={ · 249 unmodified lines | |||
| 250 | {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_QP, INT_MIN, INT_MAX, V|D, "debug"}, | 250 | {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_QP, INT_MIN, INT_MAX, V|D, "debug"}, |
| 251 | {"vis_mb_type", "visualize block types", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, | 251 | {"vis_mb_type", "visualize block types", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, |
| 252 | {"buffers", "picture buffer allocations", 0, FF_OPT_TYPE_CONST, FF_DEBUG_BUFFERS, INT_MIN, INT_MAX, V|D, "debug"}, | 252 | {"buffers", "picture buffer allocations", 0, FF_OPT_TYPE_CONST, FF_DEBUG_BUFFERS, INT_MIN, INT_MAX, V|D, "debug"}, |
| 253 | {"thread_ops", "threading operations", 0, FF_OPT_TYPE_CONST, FF_DEBUG_THREADS, INT_MIN, INT_MAX, V|D, "debug"}, | ||
| 253 | {"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|D, "debug_mv"}, | 254 | {"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|D, "debug_mv"}, |
| 254 | {"pf", "forward predicted MVs of P-frames", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_P_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, | 255 | {"pf", "forward predicted MVs of P-frames", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_P_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, |
| 255 | {"bf", "forward predicted MVs of B-frames", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, | 256 | {"bf", "forward predicted MVs of B-frames", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, |
| @@ -431,6 +432,9 @@ static const AVOption options[]={ · 175 unmodified lines | |||
| 431 | {"cholesky", NULL, 0, FF_OPT_TYPE_CONST, AV_LPC_TYPE_CHOLESKY, INT_MIN, INT_MAX, A|E, "lpc_type"}, | 432 | {"cholesky", NULL, 0, FF_OPT_TYPE_CONST, AV_LPC_TYPE_CHOLESKY, INT_MIN, INT_MAX, A|E, "lpc_type"}, |
| 432 | {"lpc_passes", "number of passes to use for Cholesky factorization during LPC analysis", OFFSET(lpc_passes), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, | 433 | {"lpc_passes", "number of passes to use for Cholesky factorization during LPC analysis", OFFSET(lpc_passes), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, |
| 433 | {"slices", "number of slices, used in parallelized decoding", OFFSET(slices), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|E}, | 434 | {"slices", "number of slices, used in parallelized decoding", OFFSET(slices), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|E}, |
| 435 | {"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_INT, FF_THREAD_SLICE|FF_THREAD_FRAME, 0, INT_MAX, V|E|D, "thread_type"}, | ||
| 436 | {"slice", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_SLICE, INT_MIN, INT_MAX, V|E|D, "thread_type"}, | ||
| 437 | {"frame", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_FRAME, INT_MIN, INT_MAX, V|E|D, "thread_type"}, | ||
| 434 | {NULL}, | 438 | {NULL}, |
| 435 | }; | 439 | }; |
| 436 | 440 | ||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2004 Roman Shaposhnik | 2 | * Copyright (c) 2004 Roman Shaposhnik |
| 3 | * Copyright (c) 2008 Alexander Strange (astrange@ithinksw.com) | ||
| 3 | * | 4 | * |
| 4 | * Many thanks to Steven M. Schultz for providing clever ideas and | 5 | * Many thanks to Steven M. Schultz for providing clever ideas and |
| 5 | * to Michael Niedermayer <michaelni@gmx.at> for writing initial | 6 | * to Michael Niedermayer <michaelni@gmx.at> for writing initial |
| @@ -21,9 +22,17 @@ · 15 unmodified lines | |||
| 21 | * License along with FFmpeg; if not, write to the Free Software | 22 | * License along with FFmpeg; if not, write to the Free Software |
| 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 23 | */ | 24 | */ |
| 25 | |||
| 26 | /** | ||
| 27 | * @file | ||
| 28 | * Multithreading support functions | ||
| 29 | * @see doc/multithreading.txt | ||
| 30 | */ | ||
| 31 | |||
| 24 | #include <pthread.h> | 32 | #include <pthread.h> |
| 25 | 33 | ||
| 26 | #include "avcodec.h" | 34 | #include "avcodec.h" |
| 35 | #include "thread.h" | ||
| 27 | 36 | ||
| 28 | typedef int (action_func)(AVCodecContext *c, void *arg); | 37 | typedef int (action_func)(AVCodecContext *c, void *arg); |
| 29 | typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); | 38 | typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); |
| @@ -45,6 +54,78 @@ typedef struct ThreadContext { · 15 unmodified lines | |||
| 45 | int done; | 54 | int done; |
| 46 | } ThreadContext; | 55 | } ThreadContext; |
| 47 | 56 | ||
| 57 | /// Max number of frame buffers that can be allocated when using frame threads. | ||
| 58 | #define MAX_BUFFERS 32 | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Context used by codec threads and stored in their AVCodecContext thread_opaque. | ||
| 62 | */ | ||
| 63 | typedef struct PerThreadContext { | ||
| 64 | struct FrameThreadContext *parent; | ||
| 65 | |||
| 66 | pthread_t thread; | ||
| 67 | pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread. | ||
| 68 | pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change. | ||
| 69 | pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish. | ||
| 70 | |||
| 71 | pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext. | ||
| 72 | pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond. | ||
| 73 | |||
| 74 | AVCodecContext *avctx; ///< Context used to decode packets passed to this thread. | ||
| 75 | |||
| 76 | AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding). | ||
| 77 | int allocated_buf_size; ///< Size allocated for avpkt.data | ||
| 78 | |||
| 79 | AVFrame frame; ///< Output frame (for decoding) or input (for encoding). | ||
| 80 | int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. | ||
| 81 | int result; ///< The result of the last codec decode/encode() call. | ||
| 82 | |||
| 83 | enum { | ||
| 84 | STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. | ||
| 85 | STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). | ||
| 86 | STATE_GET_BUFFER, /**< | ||
| 87 | * Set when the codec calls get_buffer(). | ||
| 88 | * State is returned to STATE_SETTING_UP afterwards. | ||
| 89 | */ | ||
| 90 | STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). | ||
| 91 | } state; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * Array of frames passed to ff_thread_release_buffer(). | ||
| 95 | * Frames are released after all threads referencing them are finished. | ||
| 96 | */ | ||
| 97 | AVFrame released_buffers[MAX_BUFFERS]; | ||
| 98 | int num_released_buffers; | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Array of progress values used by ff_thread_get_buffer(). | ||
| 102 | */ | ||
| 103 | int progress[MAX_BUFFERS][2]; | ||
| 104 | uint8_t progress_used[MAX_BUFFERS]; | ||
| 105 | |||
| 106 | AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() | ||
| 107 | } PerThreadContext; | ||
| 108 | |||
| 109 | /** | ||
| 110 | * Context stored in the client AVCodecContext thread_opaque. | ||
| 111 | */ | ||
| 112 | typedef struct FrameThreadContext { | ||
| 113 | PerThreadContext *threads; ///< The contexts for each thread. | ||
| 114 | PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. | ||
| 115 | |||
| 116 | pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). | ||
| 117 | |||
| 118 | int next_decoding; ///< The next context to submit a packet to. | ||
| 119 | int next_finished; ///< The next context to return output from. | ||
| 120 | |||
| 121 | int delaying; /**< | ||
| 122 | * Set for the first N packets, where N is the number of threads. | ||
| 123 | * While it is set, ff_thread_en/decode_frame won't return any results. | ||
| 124 | */ | ||
| 125 | |||
| 126 | int die; ///< Set when threads should exit. | ||
| 127 | } FrameThreadContext; | ||
| 128 | |||
| 48 | static void* attribute_align_arg worker(void *v) | 129 | static void* attribute_align_arg worker(void *v) |
| 49 | { | 130 | { |
| 50 | AVCodecContext *avctx = v; | 131 | AVCodecContext *avctx = v; |
| @@ -84,7 +165,7 @@ static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int t · 33 unmodified lines | |||
| 84 | pthread_mutex_unlock(&c->current_job_lock); | 165 | pthread_mutex_unlock(&c->current_job_lock); |
| 85 | } | 166 | } |
| 86 | 167 | ||
| 87 | void avcodec_thread_free(AVCodecContext *avctx) | 168 | static void thread_free(AVCodecContext *avctx) |
| 88 | { | 169 | { |
| 89 | ThreadContext *c = avctx->thread_opaque; | 170 | ThreadContext *c = avctx->thread_opaque; |
| 90 | int i; | 171 | int i; |
| @@ -109,6 +190,9 @@ static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void · 18 unmodified lines | |||
| 109 | ThreadContext *c= avctx->thread_opaque; | 190 | ThreadContext *c= avctx->thread_opaque; |
| 110 | int dummy_ret; | 191 | int dummy_ret; |
| 111 | 192 | ||
| 193 | if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1) | ||
| 194 | return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size); | ||
| 195 | |||
| 112 | if (job_count <= 0) | 196 | if (job_count <= 0) |
| 113 | return 0; | 197 | return 0; |
| 114 | 198 | ||
| @@ -140,12 +224,11 @@ static int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, v · 25 unmodified lines | |||
| 140 | return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0); | 224 | return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0); |
| 141 | } | 225 | } |
| 142 | 226 | ||
| 143 | int avcodec_thread_init(AVCodecContext *avctx, int thread_count) | 227 | static int thread_init(AVCodecContext *avctx) |
| 144 | { | 228 | { |
| 145 | int i; | 229 | int i; |
| 146 | ThreadContext *c; | 230 | ThreadContext *c; |
| 147 | 231 | int thread_count = avctx->thread_count; | |
| 148 | avctx->thread_count = thread_count; | ||
| 149 | 232 | ||
| 150 | if (thread_count <= 1) | 233 | if (thread_count <= 1) |
| 151 | return 0; | 234 | return 0; |
| @@ -184,3 +267,634 @@ int avcodec_thread_init(AVCodecContext *avctx, int thread_count) · 32 unmodified lines | |||
| 184 | avctx->execute2 = avcodec_thread_execute2; | 267 | avctx->execute2 = avcodec_thread_execute2; |
| 185 | return 0; | 268 | return 0; |
| 186 | } | 269 | } |
| 270 | |||
| 271 | /** | ||
| 272 | * Codec worker thread. | ||
| 273 | * | ||
| 274 | * Automatically calls ff_thread_finish_setup() if the codec does | ||
| 275 | * not provide an update_thread_context method, or if the codec returns | ||
| 276 | * before calling it. | ||
| 277 | */ | ||
| 278 | static attribute_align_arg void *frame_worker_thread(void *arg) | ||
| 279 | { | ||
| 280 | PerThreadContext *p = arg; | ||
| 281 | FrameThreadContext *fctx = p->parent; | ||
| 282 | AVCodecContext *avctx = p->avctx; | ||
| 283 | AVCodec *codec = avctx->codec; | ||
| 284 | |||
| 285 | while (1) { | ||
| 286 | if (p->state == STATE_INPUT_READY && !fctx->die) { | ||
| 287 | pthread_mutex_lock(&p->mutex); | ||
| 288 | while (p->state == STATE_INPUT_READY && !fctx->die) | ||
| 289 | pthread_cond_wait(&p->input_cond, &p->mutex); | ||
| 290 | pthread_mutex_unlock(&p->mutex); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (fctx->die) break; | ||
| 294 | |||
| 295 | if (!codec->update_thread_context) ff_thread_finish_setup(avctx); | ||
| 296 | |||
| 297 | pthread_mutex_lock(&p->mutex); | ||
| 298 | avcodec_get_frame_defaults(&p->frame); | ||
| 299 | p->got_frame = 0; | ||
| 300 | p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt); | ||
| 301 | |||
| 302 | if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx); | ||
| 303 | |||
| 304 | p->state = STATE_INPUT_READY; | ||
| 305 | |||
| 306 | pthread_mutex_lock(&p->progress_mutex); | ||
| 307 | pthread_cond_signal(&p->output_cond); | ||
| 308 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 309 | |||
| 310 | pthread_mutex_unlock(&p->mutex); | ||
| 311 | } | ||
| 312 | |||
| 313 | return NULL; | ||
| 314 | } | ||
| 315 | |||
| 316 | /** | ||
| 317 | * Updates the next thread's AVCodecContext with values from the reference thread's context. | ||
| 318 | * | ||
| 319 | * @param dst The destination context. | ||
| 320 | * @param src The source context. | ||
| 321 | * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread | ||
| 322 | */ | ||
| 323 | static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user) | ||
| 324 | { | ||
| 325 | int err = 0; | ||
| 326 | |||
| 327 | if (dst != src) { | ||
| 328 | dst->sub_id = src->sub_id; | ||
| 329 | dst->time_base = src->time_base; | ||
| 330 | dst->width = src->width; | ||
| 331 | dst->height = src->height; | ||
| 332 | dst->pix_fmt = src->pix_fmt; | ||
| 333 | |||
| 334 | dst->has_b_frames = src->has_b_frames; | ||
| 335 | dst->idct_algo = src->idct_algo; | ||
| 336 | dst->slice_count = src->slice_count; | ||
| 337 | |||
| 338 | dst->bits_per_coded_sample = src->bits_per_coded_sample; | ||
| 339 | dst->sample_aspect_ratio = src->sample_aspect_ratio; | ||
| 340 | dst->dtg_active_format = src->dtg_active_format; | ||
| 341 | |||
| 342 | dst->profile = src->profile; | ||
| 343 | dst->level = src->level; | ||
| 344 | |||
| 345 | dst->bits_per_raw_sample = src->bits_per_raw_sample; | ||
| 346 | dst->ticks_per_frame = src->ticks_per_frame; | ||
| 347 | dst->color_primaries = src->color_primaries; | ||
| 348 | |||
| 349 | dst->color_trc = src->color_trc; | ||
| 350 | dst->colorspace = src->colorspace; | ||
| 351 | dst->color_range = src->color_range; | ||
| 352 | dst->chroma_sample_location = src->chroma_sample_location; | ||
| 353 | } | ||
| 354 | |||
| 355 | if (for_user) { | ||
| 356 | dst->coded_frame = src->coded_frame; | ||
| 357 | dst->has_b_frames += src->thread_count - 1; | ||
| 358 | } else { | ||
| 359 | if (dst->codec->update_thread_context) | ||
| 360 | err = dst->codec->update_thread_context(dst, src); | ||
| 361 | } | ||
| 362 | |||
| 363 | return err; | ||
| 364 | } | ||
| 365 | |||
| 366 | /** | ||
| 367 | * Update the next thread's AVCodecContext with values set by the user. | ||
| 368 | * | ||
| 369 | * @param dst The destination context. | ||
| 370 | * @param src The source context. | ||
| 371 | */ | ||
| 372 | static void update_context_from_user(AVCodecContext *dst, AVCodecContext *src) | ||
| 373 | { | ||
| 374 | #define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s); | ||
| 375 | dst->flags = src->flags; | ||
| 376 | |||
| 377 | dst->draw_horiz_band= src->draw_horiz_band; | ||
| 378 | dst->get_buffer = src->get_buffer; | ||
| 379 | dst->release_buffer = src->release_buffer; | ||
| 380 | |||
| 381 | dst->opaque = src->opaque; | ||
| 382 | dst->hurry_up = src->hurry_up; | ||
| 383 | dst->dsp_mask = src->dsp_mask; | ||
| 384 | dst->debug = src->debug; | ||
| 385 | dst->debug_mv = src->debug_mv; | ||
| 386 | |||
| 387 | dst->slice_flags = src->slice_flags; | ||
| 388 | dst->flags2 = src->flags2; | ||
| 389 | |||
| 390 | copy_fields(skip_loop_filter, bidir_refine); | ||
| 391 | |||
| 392 | dst->frame_number = src->frame_number; | ||
| 393 | dst->reordered_opaque = src->reordered_opaque; | ||
| 394 | #undef copy_fields | ||
| 395 | } | ||
| 396 | |||
| 397 | static void free_progress(AVFrame *f) | ||
| 398 | { | ||
| 399 | PerThreadContext *p = f->owner->thread_opaque; | ||
| 400 | int *progress = f->thread_opaque; | ||
| 401 | |||
| 402 | p->progress_used[(progress - p->progress[0]) / 2] = 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | /// Releases the buffers that this decoding thread was the last user of. | ||
| 406 | static void release_delayed_buffers(PerThreadContext *p) | ||
| 407 | { | ||
| 408 | FrameThreadContext *fctx = p->parent; | ||
| 409 | |||
| 410 | while (p->num_released_buffers > 0) { | ||
| 411 | AVFrame *f = &p->released_buffers[--p->num_released_buffers]; | ||
| 412 | |||
| 413 | pthread_mutex_lock(&fctx->buffer_mutex); | ||
| 414 | free_progress(f); | ||
| 415 | f->thread_opaque = NULL; | ||
| 416 | |||
| 417 | f->owner->release_buffer(f->owner, f); | ||
| 418 | pthread_mutex_unlock(&fctx->buffer_mutex); | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | static int submit_packet(PerThreadContext *p, AVPacket *avpkt) | ||
| 423 | { | ||
| 424 | FrameThreadContext *fctx = p->parent; | ||
| 425 | PerThreadContext *prev_thread = fctx->prev_thread; | ||
| 426 | AVCodec *codec = p->avctx->codec; | ||
| 427 | uint8_t *buf = p->avpkt.data; | ||
| 428 | |||
| 429 | if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0; | ||
| 430 | |||
| 431 | pthread_mutex_lock(&p->mutex); | ||
| 432 | |||
| 433 | release_delayed_buffers(p); | ||
| 434 | |||
| 435 | if (prev_thread) { | ||
| 436 | int err; | ||
| 437 | if (prev_thread->state == STATE_SETTING_UP) { | ||
| 438 | pthread_mutex_lock(&prev_thread->progress_mutex); | ||
| 439 | while (prev_thread->state == STATE_SETTING_UP) | ||
| 440 | pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex); | ||
| 441 | pthread_mutex_unlock(&prev_thread->progress_mutex); | ||
| 442 | } | ||
| 443 | |||
| 444 | err = update_context_from_thread(p->avctx, prev_thread->avctx, 0); | ||
| 445 | if (err) { | ||
| 446 | pthread_mutex_unlock(&p->mutex); | ||
| 447 | return err; | ||
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 451 | av_fast_malloc(&buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE); | ||
| 452 | p->avpkt = *avpkt; | ||
| 453 | p->avpkt.data = buf; | ||
| 454 | memcpy(buf, avpkt->data, avpkt->size); | ||
| 455 | memset(buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); | ||
| 456 | |||
| 457 | p->state = STATE_SETTING_UP; | ||
| 458 | pthread_cond_signal(&p->input_cond); | ||
| 459 | pthread_mutex_unlock(&p->mutex); | ||
| 460 | |||
| 461 | /* | ||
| 462 | * If the client doesn't have a thread-safe get_buffer(), | ||
| 463 | * then decoding threads call back to the main thread, | ||
| 464 | * and it calls back to the client here. | ||
| 465 | */ | ||
| 466 | |||
| 467 | if (!p->avctx->thread_safe_callbacks && | ||
| 468 | p->avctx->get_buffer != avcodec_default_get_buffer) { | ||
| 469 | while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) { | ||
| 470 | pthread_mutex_lock(&p->progress_mutex); | ||
| 471 | while (p->state == STATE_SETTING_UP) | ||
| 472 | pthread_cond_wait(&p->progress_cond, &p->progress_mutex); | ||
| 473 | |||
| 474 | if (p->state == STATE_GET_BUFFER) { | ||
| 475 | p->result = p->avctx->get_buffer(p->avctx, p->requested_frame); | ||
| 476 | p->state = STATE_SETTING_UP; | ||
| 477 | pthread_cond_signal(&p->progress_cond); | ||
| 478 | } | ||
| 479 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | fctx->prev_thread = p; | ||
| 484 | |||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | int ff_thread_decode_frame(AVCodecContext *avctx, | ||
| 489 | AVFrame *picture, int *got_picture_ptr, | ||
| 490 | AVPacket *avpkt) | ||
| 491 | { | ||
| 492 | FrameThreadContext *fctx = avctx->thread_opaque; | ||
| 493 | int finished = fctx->next_finished; | ||
| 494 | PerThreadContext *p; | ||
| 495 | int err; | ||
| 496 | |||
| 497 | /* | ||
| 498 | * Submit a packet to the next decoding thread. | ||
| 499 | */ | ||
| 500 | |||
| 501 | p = &fctx->threads[fctx->next_decoding]; | ||
| 502 | update_context_from_user(p->avctx, avctx); | ||
| 503 | err = submit_packet(p, avpkt); | ||
| 504 | if (err) return err; | ||
| 505 | |||
| 506 | fctx->next_decoding++; | ||
| 507 | |||
| 508 | /* | ||
| 509 | * If we're still receiving the initial packets, don't return a frame. | ||
| 510 | */ | ||
| 511 | |||
| 512 | if (fctx->delaying && avpkt->size) { | ||
| 513 | if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0; | ||
| 514 | |||
| 515 | *got_picture_ptr=0; | ||
| 516 | return 0; | ||
| 517 | } | ||
| 518 | |||
| 519 | /* | ||
| 520 | * Return the next available frame from the oldest thread. | ||
| 521 | * If we're at the end of the stream, then we have to skip threads that | ||
| 522 | * didn't output a frame, because we don't want to accidentally signal | ||
| 523 | * EOF (avpkt->size == 0 && *got_picture_ptr == 0). | ||
| 524 | */ | ||
| 525 | |||
| 526 | do { | ||
| 527 | p = &fctx->threads[finished++]; | ||
| 528 | |||
| 529 | if (p->state != STATE_INPUT_READY) { | ||
| 530 | pthread_mutex_lock(&p->progress_mutex); | ||
| 531 | while (p->state != STATE_INPUT_READY) | ||
| 532 | pthread_cond_wait(&p->output_cond, &p->progress_mutex); | ||
| 533 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 534 | } | ||
| 535 | |||
| 536 | *picture = p->frame; | ||
| 537 | *got_picture_ptr = p->got_frame; | ||
| 538 | picture->pkt_dts = p->avpkt.dts; | ||
| 539 | |||
| 540 | /* | ||
| 541 | * A later call with avkpt->size == 0 may loop over all threads, | ||
| 542 | * including this one, searching for a frame to return before being | ||
| 543 | * stopped by the "finished != fctx->next_finished" condition. | ||
| 544 | * Make sure we don't mistakenly return the same frame again. | ||
| 545 | */ | ||
| 546 | p->got_frame = 0; | ||
| 547 | |||
| 548 | if (finished >= avctx->thread_count) finished = 0; | ||
| 549 | } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished); | ||
| 550 | |||
| 551 | update_context_from_thread(avctx, p->avctx, 1); | ||
| 552 | |||
| 553 | if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0; | ||
| 554 | |||
| 555 | fctx->next_finished = finished; | ||
| 556 | |||
| 557 | return p->result; | ||
| 558 | } | ||
| 559 | |||
| 560 | void ff_thread_report_progress(AVFrame *f, int n, int field) | ||
| 561 | { | ||
| 562 | PerThreadContext *p; | ||
| 563 | int *progress = f->thread_opaque; | ||
| 564 | |||
| 565 | if (!progress || progress[field] >= n) return; | ||
| 566 | |||
| 567 | p = f->owner->thread_opaque; | ||
| 568 | |||
| 569 | if (f->owner->debug&FF_DEBUG_THREADS) | ||
| 570 | av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); | ||
| 571 | |||
| 572 | pthread_mutex_lock(&p->progress_mutex); | ||
| 573 | progress[field] = n; | ||
| 574 | pthread_cond_broadcast(&p->progress_cond); | ||
| 575 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 576 | } | ||
| 577 | |||
| 578 | void ff_thread_await_progress(AVFrame *f, int n, int field) | ||
| 579 | { | ||
| 580 | PerThreadContext *p; | ||
| 581 | int *progress = f->thread_opaque; | ||
| 582 | |||
| 583 | if (!progress || progress[field] >= n) return; | ||
| 584 | |||
| 585 | p = f->owner->thread_opaque; | ||
| 586 | |||
| 587 | if (f->owner->debug&FF_DEBUG_THREADS) | ||
| 588 | av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); | ||
| 589 | |||
| 590 | pthread_mutex_lock(&p->progress_mutex); | ||
| 591 | while (progress[field] < n) | ||
| 592 | pthread_cond_wait(&p->progress_cond, &p->progress_mutex); | ||
| 593 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 594 | } | ||
| 595 | |||
| 596 | void ff_thread_finish_setup(AVCodecContext *avctx) { | ||
| 597 | PerThreadContext *p = avctx->thread_opaque; | ||
| 598 | |||
| 599 | if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; | ||
| 600 | |||
| 601 | pthread_mutex_lock(&p->progress_mutex); | ||
| 602 | p->state = STATE_SETUP_FINISHED; | ||
| 603 | pthread_cond_broadcast(&p->progress_cond); | ||
| 604 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 605 | } | ||
| 606 | |||
| 607 | /// Waits for all threads to finish. | ||
| 608 | static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count) | ||
| 609 | { | ||
| 610 | int i; | ||
| 611 | |||
| 612 | for (i = 0; i < thread_count; i++) { | ||
| 613 | PerThreadContext *p = &fctx->threads[i]; | ||
| 614 | |||
| 615 | if (p->state != STATE_INPUT_READY) { | ||
| 616 | pthread_mutex_lock(&p->progress_mutex); | ||
| 617 | while (p->state != STATE_INPUT_READY) | ||
| 618 | pthread_cond_wait(&p->output_cond, &p->progress_mutex); | ||
| 619 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 620 | } | ||
| 621 | } | ||
| 622 | } | ||
| 623 | |||
| 624 | static void frame_thread_free(AVCodecContext *avctx, int thread_count) | ||
| 625 | { | ||
| 626 | FrameThreadContext *fctx = avctx->thread_opaque; | ||
| 627 | AVCodec *codec = avctx->codec; | ||
| 628 | int i; | ||
| 629 | |||
| 630 | park_frame_worker_threads(fctx, thread_count); | ||
| 631 | |||
| 632 | if (fctx->prev_thread) | ||
| 633 | update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0); | ||
| 634 | |||
| 635 | fctx->die = 1; | ||
| 636 | |||
| 637 | for (i = 0; i < thread_count; i++) { | ||
| 638 | PerThreadContext *p = &fctx->threads[i]; | ||
| 639 | |||
| 640 | pthread_mutex_lock(&p->mutex); | ||
| 641 | pthread_cond_signal(&p->input_cond); | ||
| 642 | pthread_mutex_unlock(&p->mutex); | ||
| 643 | |||
| 644 | pthread_join(p->thread, NULL); | ||
| 645 | |||
| 646 | if (codec->close) | ||
| 647 | codec->close(p->avctx); | ||
| 648 | |||
| 649 | avctx->codec = NULL; | ||
| 650 | |||
| 651 | release_delayed_buffers(p); | ||
| 652 | } | ||
| 653 | |||
| 654 | for (i = 0; i < thread_count; i++) { | ||
| 655 | PerThreadContext *p = &fctx->threads[i]; | ||
| 656 | |||
| 657 | avcodec_default_free_buffers(p->avctx); | ||
| 658 | |||
| 659 | pthread_mutex_destroy(&p->mutex); | ||
| 660 | pthread_mutex_destroy(&p->progress_mutex); | ||
| 661 | pthread_cond_destroy(&p->input_cond); | ||
| 662 | pthread_cond_destroy(&p->progress_cond); | ||
| 663 | pthread_cond_destroy(&p->output_cond); | ||
| 664 | av_freep(&p->avpkt.data); | ||
| 665 | |||
| 666 | if (i) | ||
| 667 | av_freep(&p->avctx->priv_data); | ||
| 668 | |||
| 669 | av_freep(&p->avctx); | ||
| 670 | } | ||
| 671 | |||
| 672 | av_freep(&fctx->threads); | ||
| 673 | pthread_mutex_destroy(&fctx->buffer_mutex); | ||
| 674 | av_freep(&avctx->thread_opaque); | ||
| 675 | } | ||
| 676 | |||
| 677 | static int frame_thread_init(AVCodecContext *avctx) | ||
| 678 | { | ||
| 679 | int thread_count = avctx->thread_count; | ||
| 680 | AVCodec *codec = avctx->codec; | ||
| 681 | AVCodecContext *src = avctx; | ||
| 682 | FrameThreadContext *fctx; | ||
| 683 | int i, err = 0; | ||
| 684 | |||
| 685 | avctx->thread_opaque = fctx = av_mallocz(sizeof(FrameThreadContext)); | ||
| 686 | |||
| 687 | fctx->threads = av_mallocz(sizeof(PerThreadContext) * thread_count); | ||
| 688 | pthread_mutex_init(&fctx->buffer_mutex, NULL); | ||
| 689 | fctx->delaying = 1; | ||
| 690 | |||
| 691 | for (i = 0; i < thread_count; i++) { | ||
| 692 | AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); | ||
| 693 | PerThreadContext *p = &fctx->threads[i]; | ||
| 694 | |||
| 695 | pthread_mutex_init(&p->mutex, NULL); | ||
| 696 | pthread_mutex_init(&p->progress_mutex, NULL); | ||
| 697 | pthread_cond_init(&p->input_cond, NULL); | ||
| 698 | pthread_cond_init(&p->progress_cond, NULL); | ||
| 699 | pthread_cond_init(&p->output_cond, NULL); | ||
| 700 | |||
| 701 | p->parent = fctx; | ||
| 702 | p->avctx = copy; | ||
| 703 | |||
| 704 | *copy = *src; | ||
| 705 | copy->thread_opaque = p; | ||
| 706 | copy->pkt = &p->avpkt; | ||
| 707 | |||
| 708 | if (!i) { | ||
| 709 | src = copy; | ||
| 710 | |||
| 711 | if (codec->init) | ||
| 712 | err = codec->init(copy); | ||
| 713 | |||
| 714 | update_context_from_thread(avctx, copy, 1); | ||
| 715 | } else { | ||
| 716 | copy->is_copy = 1; | ||
| 717 | copy->priv_data = av_malloc(codec->priv_data_size); | ||
| 718 | memcpy(copy->priv_data, src->priv_data, codec->priv_data_size); | ||
| 719 | |||
| 720 | if (codec->init_thread_copy) | ||
| 721 | err = codec->init_thread_copy(copy); | ||
| 722 | } | ||
| 723 | |||
| 724 | if (err) goto error; | ||
| 725 | |||
| 726 | pthread_create(&p->thread, NULL, frame_worker_thread, p); | ||
| 727 | } | ||
| 728 | |||
| 729 | return 0; | ||
| 730 | |||
| 731 | error: | ||
| 732 | frame_thread_free(avctx, i+1); | ||
| 733 | |||
| 734 | return err; | ||
| 735 | } | ||
| 736 | |||
| 737 | void ff_thread_flush(AVCodecContext *avctx) | ||
| 738 | { | ||
| 739 | FrameThreadContext *fctx = avctx->thread_opaque; | ||
| 740 | |||
| 741 | if (!avctx->thread_opaque) return; | ||
| 742 | |||
| 743 | park_frame_worker_threads(fctx, avctx->thread_count); | ||
| 744 | |||
| 745 | if (fctx->prev_thread) | ||
| 746 | update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0); | ||
| 747 | |||
| 748 | fctx->next_decoding = fctx->next_finished = 0; | ||
| 749 | fctx->delaying = 1; | ||
| 750 | fctx->prev_thread = NULL; | ||
| 751 | } | ||
| 752 | |||
| 753 | static int *allocate_progress(PerThreadContext *p) | ||
| 754 | { | ||
| 755 | int i; | ||
| 756 | |||
| 757 | for (i = 0; i < MAX_BUFFERS; i++) | ||
| 758 | if (!p->progress_used[i]) break; | ||
| 759 | |||
| 760 | if (i == MAX_BUFFERS) { | ||
| 761 | av_log(p->avctx, AV_LOG_ERROR, "allocate_progress() overflow\n"); | ||
| 762 | return NULL; | ||
| 763 | } | ||
| 764 | |||
| 765 | p->progress_used[i] = 1; | ||
| 766 | |||
| 767 | return p->progress[i]; | ||
| 768 | } | ||
| 769 | |||
| 770 | int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) | ||
| 771 | { | ||
| 772 | PerThreadContext *p = avctx->thread_opaque; | ||
| 773 | int *progress, err; | ||
| 774 | |||
| 775 | f->owner = avctx; | ||
| 776 | |||
| 777 | if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { | ||
| 778 | f->thread_opaque = NULL; | ||
| 779 | return avctx->get_buffer(avctx, f); | ||
| 780 | } | ||
| 781 | |||
| 782 | if (p->state != STATE_SETTING_UP) { | ||
| 783 | av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); | ||
| 784 | return -1; | ||
| 785 | } | ||
| 786 | |||
| 787 | pthread_mutex_lock(&p->parent->buffer_mutex); | ||
| 788 | f->thread_opaque = progress = allocate_progress(p); | ||
| 789 | |||
| 790 | if (!progress) { | ||
| 791 | pthread_mutex_unlock(&p->parent->buffer_mutex); | ||
| 792 | return -1; | ||
| 793 | } | ||
| 794 | |||
| 795 | progress[0] = | ||
| 796 | progress[1] = -1; | ||
| 797 | |||
| 798 | if (avctx->thread_safe_callbacks || | ||
| 799 | avctx->get_buffer == avcodec_default_get_buffer) { | ||
| 800 | err = avctx->get_buffer(avctx, f); | ||
| 801 | } else { | ||
| 802 | p->requested_frame = f; | ||
| 803 | p->state = STATE_GET_BUFFER; | ||
| 804 | pthread_mutex_lock(&p->progress_mutex); | ||
| 805 | pthread_cond_signal(&p->progress_cond); | ||
| 806 | |||
| 807 | while (p->state != STATE_SETTING_UP) | ||
| 808 | pthread_cond_wait(&p->progress_cond, &p->progress_mutex); | ||
| 809 | |||
| 810 | err = p->result; | ||
| 811 | |||
| 812 | pthread_mutex_unlock(&p->progress_mutex); | ||
| 813 | } | ||
| 814 | |||
| 815 | pthread_mutex_unlock(&p->parent->buffer_mutex); | ||
| 816 | |||
| 817 | /* | ||
| 818 | * Buffer age is difficult to keep track of between | ||
| 819 | * multiple threads, and the optimizations it allows | ||
| 820 | * are not worth the effort. It is disabled for now. | ||
| 821 | */ | ||
| 822 | f->age = INT_MAX; | ||
| 823 | |||
| 824 | return err; | ||
| 825 | } | ||
| 826 | |||
| 827 | void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) | ||
| 828 | { | ||
| 829 | PerThreadContext *p = avctx->thread_opaque; | ||
| 830 | |||
| 831 | if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { | ||
| 832 | avctx->release_buffer(avctx, f); | ||
| 833 | return; | ||
| 834 | } | ||
| 835 | |||
| 836 | if (p->num_released_buffers >= MAX_BUFFERS) { | ||
| 837 | av_log(p->avctx, AV_LOG_ERROR, "too many thread_release_buffer calls!\n"); | ||
| 838 | return; | ||
| 839 | } | ||
| 840 | |||
| 841 | if(avctx->debug & FF_DEBUG_BUFFERS) | ||
| 842 | av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p, %d buffers used\n", | ||
| 843 | f, f->owner->internal_buffer_count); | ||
| 844 | |||
| 845 | p->released_buffers[p->num_released_buffers++] = *f; | ||
| 846 | memset(f->data, 0, sizeof(f->data)); | ||
| 847 | } | ||
| 848 | |||
| 849 | /** | ||
| 850 | * Set the threading algorithms used. | ||
| 851 | * | ||
| 852 | * Threading requires more than one thread. | ||
| 853 | * Frame threading requires entire frames to be passed to the codec, | ||
| 854 | * and introduces extra decoding delay, so is incompatible with low_delay. | ||
| 855 | * | ||
| 856 | * @param avctx The context. | ||
| 857 | */ | ||
| 858 | static void validate_thread_parameters(AVCodecContext *avctx) | ||
| 859 | { | ||
| 860 | int frame_threading_supported = (avctx->codec->capabilities & CODEC_CAP_FRAME_THREADS) | ||
| 861 | && !(avctx->flags & CODEC_FLAG_TRUNCATED) | ||
| 862 | && !(avctx->flags & CODEC_FLAG_LOW_DELAY) | ||
| 863 | && !(avctx->flags2 & CODEC_FLAG2_CHUNKS); | ||
| 864 | if (avctx->thread_count == 1) { | ||
| 865 | avctx->active_thread_type = 0; | ||
| 866 | } else if (frame_threading_supported && (avctx->thread_type & FF_THREAD_FRAME)) { | ||
| 867 | avctx->active_thread_type = FF_THREAD_FRAME; | ||
| 868 | } else { | ||
| 869 | avctx->active_thread_type = FF_THREAD_SLICE; | ||
| 870 | } | ||
| 871 | } | ||
| 872 | |||
| 873 | int avcodec_thread_init(AVCodecContext *avctx, int thread_count) | ||
| 874 | { | ||
| 875 | if (avctx->thread_opaque) { | ||
| 876 | av_log(avctx, AV_LOG_ERROR, "avcodec_thread_init is ignored after avcodec_open\n"); | ||
| 877 | return -1; | ||
| 878 | } | ||
| 879 | |||
| 880 | avctx->thread_count = FFMAX(1, thread_count); | ||
| 881 | |||
| 882 | if (avctx->codec) { | ||
| 883 | validate_thread_parameters(avctx); | ||
| 884 | |||
| 885 | if (avctx->active_thread_type&FF_THREAD_SLICE) | ||
| 886 | return thread_init(avctx); | ||
| 887 | else if (avctx->active_thread_type&FF_THREAD_FRAME) | ||
| 888 | return frame_thread_init(avctx); | ||
| 889 | } | ||
| 890 | |||
| 891 | return 0; | ||
| 892 | } | ||
| 893 | |||
| 894 | void avcodec_thread_free(AVCodecContext *avctx) | ||
| 895 | { | ||
| 896 | if (avctx->active_thread_type&FF_THREAD_FRAME) | ||
| 897 | frame_thread_free(avctx, avctx->thread_count); | ||
| 898 | else | ||
| 899 | thread_free(avctx); | ||
| 900 | } | ||
| @@ -0,0 +1,111 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008 Alexander Strange <astrange@ithinksw.com> | ||
| 3 | * | ||
| 4 | * This file is part of FFmpeg. | ||
| 5 | * | ||
| 6 | * FFmpeg is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU Lesser General Public | ||
| 8 | * License as published by the Free Software Foundation; either | ||
| 9 | * version 2.1 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * Lesser General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU Lesser General Public | ||
| 17 | * License along with FFmpeg; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | /** | ||
| 22 | * @file | ||
| 23 | * Multithreading support functions | ||
| 24 | * @author Alexander Strange <astrange@ithinksw.com> | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef AVCODEC_THREAD_H | ||
| 28 | #define AVCODEC_THREAD_H | ||
| 29 | |||
| 30 | #include "config.h" | ||
| 31 | #include "avcodec.h" | ||
| 32 | |||
| 33 | /** | ||
| 34 | * Waits for decoding threads to finish and resets internal | ||
| 35 | * state. Called by avcodec_flush_buffers(). | ||
| 36 | * | ||
| 37 | * @param avctx The context. | ||
| 38 | */ | ||
| 39 | void ff_thread_flush(AVCodecContext *avctx); | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Submits a new frame to a decoding thread. | ||
| 43 | * Returns the next available frame in picture. *got_picture_ptr | ||
| 44 | * will be 0 if none is available. | ||
| 45 | * | ||
| 46 | * Parameters are the same as avcodec_decode_video2(). | ||
| 47 | */ | ||
| 48 | int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture, | ||
| 49 | int *got_picture_ptr, AVPacket *avpkt); | ||
| 50 | |||
| 51 | /** | ||
| 52 | * If the codec defines update_thread_context(), call this | ||
| 53 | * when they are ready for the next thread to start decoding | ||
| 54 | * the next frame. After calling it, do not change any variables | ||
| 55 | * read by the update_thread_context() method, or call ff_thread_get_buffer(). | ||
| 56 | * | ||
| 57 | * @param avctx The context. | ||
| 58 | */ | ||
| 59 | void ff_thread_finish_setup(AVCodecContext *avctx); | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Notifies later decoding threads when part of their reference picture | ||
| 63 | * is ready. | ||
| 64 | * Call this when some part of the picture is finished decoding. | ||
| 65 | * Later calls with lower values of progress have no effect. | ||
| 66 | * | ||
| 67 | * @param f The picture being decoded. | ||
| 68 | * @param progress Value, in arbitrary units, of how much of the picture has decoded. | ||
| 69 | * @param field The field being decoded, for field-picture codecs. | ||
| 70 | * 0 for top field or frame pictures, 1 for bottom field. | ||
| 71 | */ | ||
| 72 | void ff_thread_report_progress(AVFrame *f, int progress, int field); | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Waits for earlier decoding threads to finish reference pictures | ||
| 76 | * Call this before accessing some part of a picture, with a given | ||
| 77 | * value for progress, and it will return after the responsible decoding | ||
| 78 | * thread calls ff_thread_report_progress() with the same or | ||
| 79 | * higher value for progress. | ||
| 80 | * | ||
| 81 | * @param f The picture being referenced. | ||
| 82 | * @param progress Value, in arbitrary units, to wait for. | ||
| 83 | * @param field The field being referenced, for field-picture codecs. | ||
| 84 | * 0 for top field or frame pictures, 1 for bottom field. | ||
| 85 | */ | ||
| 86 | void ff_thread_await_progress(AVFrame *f, int progress, int field); | ||
| 87 | |||
| 88 | /** | ||
| 89 | * Wrapper around get_buffer() for frame-multithreaded codecs. | ||
| 90 | * Call this function instead of avctx->get_buffer(f). | ||
| 91 | * Cannot be called after the codec has called ff_thread_finish_setup(). | ||
| 92 | * | ||
| 93 | * @param avctx The current context. | ||
| 94 | * @param f The frame to write into. | ||
| 95 | */ | ||
| 96 | int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f); | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Wrapper around release_buffer() frame-for multithreaded codecs. | ||
| 100 | * Call this function instead of avctx->release_buffer(f). | ||
| 101 | * The AVFrame will be copied and the actual release_buffer() call | ||
| 102 | * will be performed later. The contents of data pointed to by the | ||
| 103 | * AVFrame should not be changed until ff_thread_get_buffer() is called | ||
| 104 | * on it. | ||
| 105 | * | ||
| 106 | * @param avctx The current context. | ||
| 107 | * @param f The picture being released. | ||
| 108 | */ | ||
| 109 | void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f); | ||
| 110 | |||
| 111 | #endif /* AVCODEC_THREAD_H */ | ||
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include "dsputil.h" | 37 | #include "dsputil.h" |
| 38 | #include "libavutil/opt.h" | 38 | #include "libavutil/opt.h" |
| 39 | #include "imgconvert.h" | 39 | #include "imgconvert.h" |
| 40 | #include "thread.h" | ||
| 40 | #include "audioconvert.h" | 41 | #include "audioconvert.h" |
| 41 | #include "internal.h" | 42 | #include "internal.h" |
| 42 | #include <stdlib.h> | 43 | #include <stdlib.h> |
| @@ -261,6 +262,11 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ · 218 unmodified lines | |||
| 261 | (*picture_number)++; | 262 | (*picture_number)++; |
| 262 | 263 | ||
| 263 | if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ | 264 | if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ |
| 265 | if(s->active_thread_type&FF_THREAD_FRAME) { | ||
| 266 | av_log_missing_feature(s, "Width/height changing with frame threads is", 0); | ||
| 267 | return -1; | ||
| 268 | } | ||
| 269 | |||
| 264 | for(i=0; i<4; i++){ | 270 | for(i=0; i<4; i++){ |
| 265 | av_freep(&buf->base[i]); | 271 | av_freep(&buf->base[i]); |
| 266 | buf->data[i]= NULL; | 272 | buf->data[i]= NULL; |
| @@ -532,6 +538,14 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) · 265 unmodified lines | |||
| 532 | goto free_and_end; | 538 | goto free_and_end; |
| 533 | } | 539 | } |
| 534 | avctx->frame_number = 0; | 540 | avctx->frame_number = 0; |
| 541 | |||
| 542 | if (HAVE_THREADS && !avctx->thread_opaque) { | ||
| 543 | ret = avcodec_thread_init(avctx, avctx->thread_count); | ||
| 544 | if (ret < 0) { | ||
| 545 | goto free_and_end; | ||
| 546 | } | ||
| 547 | } | ||
| 548 | |||
| 535 | if (avctx->codec->max_lowres < avctx->lowres) { | 549 | if (avctx->codec->max_lowres < avctx->lowres) { |
| 536 | av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n", | 550 | av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n", |
| 537 | avctx->codec->max_lowres); | 551 | avctx->codec->max_lowres); |
| @@ -543,7 +557,7 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) · 5 unmodified lines | |||
| 543 | avctx->pts_correction_last_pts = | 557 | avctx->pts_correction_last_pts = |
| 544 | avctx->pts_correction_last_dts = INT64_MIN; | 558 | avctx->pts_correction_last_dts = INT64_MIN; |
| 545 | 559 | ||
| 546 | if(avctx->codec->init){ | 560 | if(avctx->codec->init && !(avctx->active_thread_type&FF_THREAD_FRAME)){ |
| 547 | ret = avctx->codec->init(avctx); | 561 | ret = avctx->codec->init(avctx); |
| 548 | if (ret < 0) { | 562 | if (ret < 0) { |
| 549 | goto free_and_end; | 563 | goto free_and_end; |
| @@ -674,13 +688,18 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi · 124 unmodified lines | |||
| 674 | 688 | ||
| 675 | avctx->pkt = avpkt; | 689 | avctx->pkt = avpkt; |
| 676 | 690 | ||
| 677 | if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ | 691 | if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ |
| 678 | ret = avctx->codec->decode(avctx, picture, got_picture_ptr, | 692 | if (HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) |
| 679 | avpkt); | 693 | ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, |
| 694 | avpkt); | ||
| 695 | else { | ||
| 696 | ret = avctx->codec->decode(avctx, picture, got_picture_ptr, | ||
| 697 | avpkt); | ||
| 698 | picture->pkt_dts= avpkt->dts; | ||
| 699 | } | ||
| 680 | 700 | ||
| 681 | emms_c(); //needed to avoid an emms_c() call before every return; | 701 | emms_c(); //needed to avoid an emms_c() call before every return; |
| 682 | 702 | ||
| 683 | picture->pkt_dts= avpkt->dts; | ||
| 684 | picture->best_effort_timestamp = guess_correct_pts(avctx, | 703 | picture->best_effort_timestamp = guess_correct_pts(avctx, |
| 685 | picture->pkt_pts, | 704 | picture->pkt_pts, |
| 686 | picture->pkt_dts); | 705 | picture->pkt_dts); |
| @@ -809,6 +828,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) · 122 unmodified lines | |||
| 809 | if(avctx->codec && avctx->codec->encode) | 828 | if(avctx->codec && avctx->codec->encode) |
| 810 | av_freep(&avctx->extradata); | 829 | av_freep(&avctx->extradata); |
| 811 | avctx->codec = NULL; | 830 | avctx->codec = NULL; |
| 831 | avctx->active_thread_type = 0; | ||
| 812 | entangled_thread_counter--; | 832 | entangled_thread_counter--; |
| 813 | 833 | ||
| 814 | /* Release any user-supplied mutex. */ | 834 | /* Release any user-supplied mutex. */ |
| @@ -1070,6 +1090,8 @@ void avcodec_init(void) · 255 unmodified lines | |||
| 1070 | 1090 | ||
| 1071 | void avcodec_flush_buffers(AVCodecContext *avctx) | 1091 | void avcodec_flush_buffers(AVCodecContext *avctx) |
| 1072 | { | 1092 | { |
| 1093 | if(HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) | ||
| 1094 | ff_thread_flush(avctx); | ||
| 1073 | if(avctx->codec->flush) | 1095 | if(avctx->codec->flush) |
| 1074 | avctx->codec->flush(avctx); | 1096 | avctx->codec->flush(avctx); |
| 1075 | } | 1097 | } |
| @@ -1270,3 +1292,30 @@ unsigned int ff_toupper4(unsigned int x) · 194 unmodified lines | |||
| 1270 | + (toupper((x>>16)&0xFF)<<16) | 1292 | + (toupper((x>>16)&0xFF)<<16) |
| 1271 | + (toupper((x>>24)&0xFF)<<24); | 1293 | + (toupper((x>>24)&0xFF)<<24); |
| 1272 | } | 1294 | } |
| 1295 | |||
| 1296 | #if !HAVE_PTHREADS | ||
| 1297 | |||
| 1298 | int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) | ||
| 1299 | { | ||
| 1300 | f->owner = avctx; | ||
| 1301 | return avctx->get_buffer(avctx, f); | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) | ||
| 1305 | { | ||
| 1306 | f->owner->release_buffer(f->owner, f); | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | void ff_thread_finish_setup(AVCodecContext *avctx) | ||
| 1310 | { | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | void ff_thread_report_progress(AVFrame *f, int progress, int field) | ||
| 1314 | { | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | void ff_thread_await_progress(AVFrame *f, int progress, int field) | ||
| 1318 | { | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | #endif | ||
| @@ -129,7 +129,13 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count){ · 128 unmodified lines | |||
| 129 | ThreadContext *c; | 129 | ThreadContext *c; |
| 130 | uint32_t threadid; | 130 | uint32_t threadid; |
| 131 | 131 | ||
| 132 | if(!(s->thread_type & FF_THREAD_SLICE)){ | ||
| 133 | av_log(s, AV_LOG_WARNING, "The requested thread algorithm is not supported with this thread library.\n"); | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 132 | s->thread_count= thread_count; | 137 | s->thread_count= thread_count; |
| 138 | s->active_thread_type= FF_THREAD_SLICE; | ||
| 133 | 139 | ||
| 134 | if (thread_count <= 1) | 140 | if (thread_count <= 1) |
| 135 | return 0; | 141 | return 0; |
| @@ -930,6 +930,12 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, · 929 unmodified lines | |||
| 930 | /* do we have a video B-frame ? */ | 930 | /* do we have a video B-frame ? */ |
| 931 | delay= st->codec->has_b_frames; | 931 | delay= st->codec->has_b_frames; |
| 932 | presentation_delayed = 0; | 932 | presentation_delayed = 0; |
| 933 | |||
| 934 | // ignore delay caused by frame threading so that the mpeg2-without-dts | ||
| 935 | // warning will not trigger | ||
| 936 | if (delay && st->codec->active_thread_type&FF_THREAD_FRAME) | ||
| 937 | delay -= st->codec->thread_count-1; | ||
| 938 | |||
| 933 | /* XXX: need has_b_frame, but cannot get it if the codec is | 939 | /* XXX: need has_b_frame, but cannot get it if the codec is |
| 934 | not initialized */ | 940 | not initialized */ |
| 935 | if (delay && | 941 | if (delay && |
| @@ -210,4 +210,15 @@ · 209 unmodified lines | |||
| 210 | type ff_##name args | 210 | type ff_##name args |
| 211 | #endif | 211 | #endif |
| 212 | 212 | ||
| 213 | /** | ||
| 214 | * Returns NULL if a threading library has not been enabled. | ||
| 215 | * Used to disable threading functions in AVCodec definitions | ||
| 216 | * when not needed. | ||
| 217 | */ | ||
| 218 | #if HAVE_THREADS | ||
| 219 | # define ONLY_IF_THREADS_ENABLED(x) x | ||
| 220 | #else | ||
| 221 | # define ONLY_IF_THREADS_ENABLED(x) NULL | ||
| 222 | #endif | ||
| 223 | |||
| 213 | #endif /* AVUTIL_INTERNAL_H */ | 224 | #endif /* AVUTIL_INTERNAL_H */ |