Ticket #1107: mpeg4-muxer-v9.patch
File mpeg4-muxer-v9.patch, 42.6 KB (added by , 6 years ago) |
---|
-
setup.py
1651 1651 add_keywords([libffmpeg_bin_dir], [libffmpeg_include_dir], 1652 1652 [libffmpeg_lib_dir, libffmpeg_bin_dir], 1653 1653 ["avcodec", "avutil"]) 1654 if "avformat" in pkgs_options[0]: 1655 add_keywords([libffmpeg_bin_dir], [libffmpeg_include_dir], 1656 [libffmpeg_lib_dir, libffmpeg_bin_dir], 1657 ["avformat", "avutil"]) 1654 1658 elif "swscale" in pkgs_options[0]: 1655 1659 add_keywords([libffmpeg_bin_dir], [libffmpeg_include_dir], 1656 1660 [libffmpeg_lib_dir, libffmpeg_bin_dir], … … 2411 2415 2412 2416 toggle_packages(enc_ffmpeg_ENABLED, "xpra.codecs.enc_ffmpeg") 2413 2417 if enc_ffmpeg_ENABLED: 2414 ffmpeg_pkgconfig = pkgconfig("libavcodec" )2418 ffmpeg_pkgconfig = pkgconfig("libavcodec", "libavformat") 2415 2419 cython_add(Extension("xpra.codecs.enc_ffmpeg.encoder", 2416 2420 ["xpra/codecs/enc_ffmpeg/encoder.pyx"]+membuffers_c, 2417 2421 **ffmpeg_pkgconfig)) -
xpra/codecs/enc_ffmpeg/encoder.pyx
6 6 import os 7 7 import weakref 8 8 from xpra.log import Logger 9 from Cython.Shadow import NULL 9 10 log = Logger("encoder", "ffmpeg") 10 11 11 12 from xpra.codecs.image_wrapper import ImageWrapper … … 17 18 SAVE_TO_FILE = os.environ.get("XPRA_SAVE_TO_FILE") 18 19 19 20 20 from libc.stdint cimport uint8_t, int64_t, uint8_t 21 DEF SEEK_SET = 0 22 DEF SEEK_CUR = 1 23 DEF SEEK_END = 2 24 SEEKS = { 25 SEEK_SET : "SET", 26 SEEK_CUR : "CUR", 27 SEEK_END : "END", 28 } 21 29 30 from libc.stdint cimport uint8_t, int64_t, uint64_t, uint32_t, uint8_t 31 22 32 cdef extern from "string.h": 33 void *memcpy(void * destination, void *source, size_t num) 23 34 void free(void * ptr) nogil 24 35 25 36 cdef extern from "../../buffers/buffers.h": … … 35 46 36 47 cdef extern from "libavutil/mem.h": 37 48 void av_free(void *ptr) 49 void *av_malloc(size_t size) 38 50 39 51 cdef extern from "libavutil/error.h": 40 52 int av_strerror(int errnum, char *errbuf, size_t errbuf_size) … … 72 84 AVPixelFormat AV_PIX_FMT_BGRA 73 85 AVPixelFormat AV_PIX_FMT_GBRP 74 86 87 88 cdef extern from "libavformat/avio.h": 89 ctypedef int AVIODataMarkerType 90 int AVIO_FLAG_WRITE 91 92 ctypedef struct AVIOInterruptCB: 93 pass 94 95 ctypedef struct AVIOContext: 96 const AVClass *av_class 97 unsigned char *buffer #Start of the buffer 98 int buffer_size #Maximum buffer size 99 unsigned char *buf_ptr #Current position in the buffer 100 unsigned char *buf_end #End of the data, may be less than 101 #buffer+buffer_size if the read function returned 102 #less data than requested, e.g. for streams where 103 #no more data has been received yet. 104 void *opaque #A private pointer, passed to the read/write/seek/... functions. 105 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size) 106 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size) 107 int64_t (*seek)(void *opaque, int64_t offset, int whence) 108 int64_t pos #position in the file of the current buffer 109 int must_flush #true if the next seek should flush 110 int eof_reached #true if eof reached 111 int write_flag #true if open for writing 112 int max_packet_size 113 unsigned long checksum 114 unsigned char *checksum_ptr 115 unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size) 116 int error #contains the error code or 0 if no error happened 117 int (*read_pause)(void *opaque, int pause) 118 int64_t (*read_seek)(void *opaque, int stream_index, int64_t timestamp, int flags) 119 int seekable 120 int64_t maxsize 121 int direct 122 int64_t bytes_read 123 int seek_count; 124 int writeout_count 125 int orig_buffer_size 126 int short_seek_threshold 127 const char *protocol_whitelist 128 const char *protocol_blacklist 129 int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size, AVIODataMarkerType type, int64_t time) 130 int ignore_boundary_point 131 AVIODataMarkerType current_type 132 int64_t last_time 133 134 AVIOContext *avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, 135 void *opaque, 136 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), 137 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), 138 int64_t (*seek)(void *opaque, int64_t offset, int whence)) 139 140 int avio_open(AVIOContext **s, const char *url, int flags) 141 int avio_close(AVIOContext *s) 142 143 75 144 cdef extern from "libavcodec/avcodec.h": 145 int CODEC_FLAG_UNALIGNED 146 int CODEC_FLAG_QSCALE 147 int CODEC_FLAG_4MV 148 int CODEC_FLAG_OUTPUT_CORRUPT 149 int CODEC_FLAG_QPEL 150 int CODEC_FLAG_GMC 151 int CODEC_FLAG_MV0 152 int CODEC_FLAG_INPUT_PRESERVED 153 int CODEC_FLAG_PASS1 154 int CODEC_FLAG_PASS2 155 int CODEC_FLAG_GRAY 156 int CODEC_FLAG_EMU_EDGE 157 int CODEC_FLAG_PSNR 158 int CODEC_FLAG_TRUNCATED 159 int CODEC_FLAG_NORMALIZE_AQP 160 int CODEC_FLAG_INTERLACED_DCT 161 int CODEC_FLAG_GLOBAL_HEADER 162 76 163 int CODEC_FLAG2_FAST 164 77 165 int CODEC_CAP_DRAW_HORIZ_BAND 78 166 int CODEC_CAP_DR1 79 167 int CODEC_CAP_TRUNCATED … … 94 182 int CODEC_CAP_LOSSLESS 95 183 96 184 ctypedef struct AVFrame: 97 uint8_t **data98 int *linesize99 int width100 int height101 int format102 int key_frame103 int64_t pts104 int coded_picture_number105 int display_picture_number106 int quality107 void *opaque185 uint8_t **data 186 int *linesize 187 int width 188 int height 189 int format 190 int key_frame 191 int64_t pts 192 int coded_picture_number 193 int display_picture_number 194 int quality 195 void *opaque 108 196 AVPictureType pict_type 109 197 ctypedef struct AVCodec: 110 int capabilities111 const char *name112 const char *long_name198 int capabilities 199 const char *name 200 const char *long_name 113 201 ctypedef struct AVDictionary: 114 202 pass 203 int AV_PKT_FLAG_KEY 204 int AV_PKT_FLAG_CORRUPT 115 205 ctypedef struct AVPacket: 206 int64_t pts 207 int64_t dts 116 208 uint8_t *data 117 int size 209 int size 210 int stream_index 211 int flags 212 AVPacketSideData *side_data 213 int side_data_elems 214 int64_t duration 215 int64_t pos 118 216 119 217 ctypedef struct AVRational: 120 218 int num … … 136 234 int delay 137 235 AVRational framerate 138 236 AVRational time_base 237 unsigned int codec_tag 139 238 140 239 ctypedef struct AVFormatContext: 141 pass 240 const AVClass *av_class 241 AVInputFormat *iformat 242 AVOutputFormat *oformat 243 void *priv_data 244 AVIOContext *pb 245 int ctx_flags 246 unsigned int nb_streams 247 AVStream **streams 248 char filename[1024] 249 int64_t start_time 250 int64_t duration 251 int bit_rate 252 unsigned int packet_size 253 int max_delay 254 int flags 255 unsigned int probesize 256 int max_analyze_duration 257 const uint8_t *key 258 int keylen 259 unsigned int nb_programs 260 AVProgram **programs 261 AVCodecID video_codec_id 262 AVCodecID audio_codec_id 263 AVCodecID subtitle_codec_id 264 unsigned int max_index_size 265 unsigned int max_picture_buffer 266 unsigned int nb_chapters 267 AVChapter **chapters 268 AVDictionary *metadata 269 int64_t start_time_realtime 270 int fps_probe_size 271 int error_recognition 272 AVIOInterruptCB interrupt_callback 273 int debug 274 int64_t max_interleave_delta 275 int strict_std_compliance 276 int event_flags 277 int max_ts_probe 278 int avoid_negative_ts 279 AVFormatInternal *internal 280 void *opaque 281 int (*io_open)(AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options) 282 void (*io_close)(AVFormatContext *s, AVIOContext *pb) 283 char *protocol_blacklist 284 char *protocol_whitelist 142 285 286 ctypedef int AVMediaType 287 ctypedef int AVFieldOrder 288 ctypedef int AVColorRange 289 ctypedef int AVColorPrimaries 290 ctypedef int AVColorTransferCharacteristic 291 ctypedef int AVColorSpace 292 ctypedef int AVChromaLocation 293 ctypedef struct AVCodecParameters: 294 AVMediaType codec_type 295 AVCodecID codec_id 296 uint32_t codec_tag 297 uint8_t *extradata 298 int extradata_size 299 int format 300 int64_t bit_rate 301 int bits_per_coded_sample 302 int bits_per_raw_sample 303 int profile 304 int level 305 int width 306 int height 307 AVRational sample_aspect_ratio 308 AVFieldOrder field_order 309 AVColorRange color_range 310 AVColorPrimaries color_primaries 311 AVColorTransferCharacteristic color_trc 312 AVColorSpace color_space 313 AVChromaLocation chroma_location 314 int video_delay 315 uint64_t channel_layout 316 int channels 317 int sample_rate 318 int block_align 319 int frame_size 320 int initial_padding 321 int trailing_padding 322 int seek_preroll 323 143 324 AVCodecID AV_CODEC_ID_H264 144 325 AVCodecID AV_CODEC_ID_H265 145 326 AVCodecID AV_CODEC_ID_VP8 … … 162 343 void av_init_packet(AVPacket *pkt) nogil 163 344 void av_packet_unref(AVPacket *pkt) nogil 164 345 346 ctypedef int AVOptionType 165 347 348 cdef extern from "libavutil/opt.h": 349 AVOptionType AV_OPT_TYPE_FLAGS 350 AVOptionType AV_OPT_TYPE_INT 351 AVOptionType AV_OPT_TYPE_INT64 352 AVOptionType AV_OPT_TYPE_DOUBLE 353 AVOptionType AV_OPT_TYPE_FLOAT 354 AVOptionType AV_OPT_TYPE_STRING 355 AVOptionType AV_OPT_TYPE_RATIONAL 356 AVOptionType AV_OPT_TYPE_BINARY #offset must point to a pointer immediately followed by an int for the length 357 AVOptionType AV_OPT_TYPE_DICT 358 AVOptionType AV_OPT_TYPE_CONST 359 AVOptionType AV_OPT_TYPE_IMAGE_SIZE 360 AVOptionType AV_OPT_TYPE_PIXEL_FMT 361 AVOptionType AV_OPT_TYPE_SAMPLE_FMT 362 AVOptionType AV_OPT_TYPE_VIDEO_RATE 363 AVOptionType AV_OPT_TYPE_DURATION 364 AVOptionType AV_OPT_TYPE_COLOR 365 AVOptionType AV_OPT_TYPE_CHANNEL_LAYOUT 366 AVOptionType AV_OPT_TYPE_BOOL 367 368 int AV_OPT_SEARCH_CHILDREN 369 int AV_OPT_SEARCH_FAKE_OBJ 370 371 ctypedef struct AVOption: 372 const char *name #short English help text 373 const char *help 374 int offset #The offset relative to the context structure where the option value is stored. It should be 0 for named constants. 375 AVOptionType type 376 int flags 377 const char *unit 378 379 const AVOption* av_opt_next(void *obj, const AVOption *prev) 380 void *av_opt_child_next(void *obj, void *prev) 381 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) 382 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val) 383 384 385 cdef extern from "libavutil/log.h": 386 ctypedef struct AVClass: 387 const char *class_name #The name of the class; usually it is the same name as the context structure type to which the AVClass is associated. 388 const char *(*item_name)(void *ctx) #A pointer to a function which returns the name of a context instance ctx associated with the class. 389 AVOption *option #a pointer to the first option specified in the class if any or NULL 390 int version #LIBAVUTIL_VERSION with which this structure was created 391 int log_level_offset_offset #Offset in the structure where log_level_offset is stored 392 int parent_log_context_offset #Offset in the structure where a pointer to the parent context for logging is stored 393 void *(*child_next)(void *obj, void *prev) #Return next AVOptions-enabled child or NULL 394 AVClass *(*child_class_next)(const AVClass *prev) #Return an AVClass corresponding to the next potential AVOptions-enabled child. 395 #AVClassCategory category #Category used for visualization (like color) This is only set if the category is equal for all objects using this class. 396 #AVClassCategory (*get_category)(void *ctx) 397 398 399 cdef extern from "libavformat/avformat.h": 400 int AVFMTCTX_NOHEADER #signal that no header is present 401 402 int AVFMT_FLAG_GENPTS #Generate missing pts even if it requires parsing future frames 403 int AVFMT_FLAG_IGNIDX #Ignore index 404 int AVFMT_FLAG_NONBLOCK #Do not block when reading packets from input 405 int AVFMT_FLAG_IGNDTS #Ignore DTS on frames that contain both DTS & PTS 406 int AVFMT_FLAG_NOFILLIN #Do not infer any values from other values, just return what is stored in the container 407 int AVFMT_FLAG_NOPARSE #Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled 408 int AVFMT_FLAG_NOBUFFER #Do not buffer frames when possible 409 int AVFMT_FLAG_CUSTOM_IO #The caller has supplied a custom AVIOContext, don't avio_close() it 410 int AVFMT_FLAG_DISCARD_CORRUPT #Discard frames marked corrupted 411 int AVFMT_FLAG_FLUSH_PACKETS #Flush the AVIOContext every packet 412 int AVFMT_FLAG_BITEXACT 413 int AVFMT_FLAG_MP4A_LATM #Enable RTP MP4A-LATM payload 414 int AVFMT_FLAG_SORT_DTS #try to interleave outputted packets by dts (using this flag can slow demuxing down) 415 int AVFMT_FLAG_PRIV_OPT #Enable use of private options by delaying codec open (this could be made default once all code is converted) 416 int AVFMT_FLAG_KEEP_SIDE_DATA #Don't merge side data but keep it separate. 417 int AVFMT_FLAG_FAST_SEEK #Enable fast, but inaccurate seeks for some formats 418 419 int AVFMT_NOFILE #Demuxer will use avio_open, no opened file should be provided by the caller 420 int AVFMT_NEEDNUMBER #Needs '%d' in filename 421 int AVFMT_SHOW_IDS #Show format stream IDs numbers 422 int AVFMT_RAWPICTURE #Format wants AVPicture structure for raw picture data. @deprecated Not used anymore 423 int AVFMT_GLOBALHEADER #Format wants global header 424 int AVFMT_NOTIMESTAMPS #Format does not need / have any timestamps 425 int AVFMT_GENERIC_INDEX #Use generic index building code 426 int AVFMT_TS_DISCONT #Format allows timestamp discontinuities. Note, muxers always require valid (monotone) timestamps 427 int AVFMT_VARIABLE_FPS #Format allows variable fps 428 int AVFMT_NODIMENSIONS #Format does not need width/height 429 int AVFMT_NOSTREAMS #Format does not require any streams 430 int AVFMT_NOBINSEARCH #Format does not allow to fall back on binary search via read_timestamp 431 int AVFMT_NOGENSEARCH #Format does not allow to fall back on generic search 432 int AVFMT_NO_BYTE_SEEK #Format does not allow seeking by bytes 433 int AVFMT_ALLOW_FLUSH #Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function 434 int AVFMT_TS_NONSTRICT #Format does not require strictly increasing timestamps, but they must still be monotonic 435 int AVFMT_TS_NEGATIVE #Format allows muxing negative timestamps. 436 int AVFMT_SEEK_TO_PTS #Seeking is based on PTS 437 438 ctypedef int AVStreamParseType 439 ctypedef struct AVInputFormat: 440 pass 441 ctypedef struct AVProgram: 442 pass 443 ctypedef struct AVChapter: 444 pass 445 ctypedef struct AVFormatInternal: 446 pass 447 ctypedef struct AVPacketSideData: 448 pass 449 ctypedef struct AVStream: 450 int index #stream index in AVFormatContext 451 int id 452 AVCodecContext *codec 453 AVRational time_base 454 int64_t start_time 455 int64_t duration 456 int64_t nb_frames #number of frames in this stream if known or 0 457 int disposition 458 #AVDiscard discard #Selects which packets can be discarded at will and do not need to be demuxed. 459 AVRational sample_aspect_ratio 460 AVDictionary *metadata 461 AVRational avg_frame_rate 462 AVPacket attached_pic 463 AVPacketSideData *side_data 464 int nb_side_data 465 int event_flags 466 int pts_wrap_bits #number of bits in pts (used for wrapping control) 467 int64_t first_dts 468 int64_t cur_dts 469 int64_t last_IP_pts 470 int last_IP_duration 471 int probe_packets 472 int codec_info_nb_frames 473 AVStreamParseType need_parsing 474 #AVPacketList *last_in_packet_buffer 475 #AVProbeData probe_data 476 int stream_identifier 477 char *recommended_encoder_configuration 478 AVCodecParameters *codecpar 479 480 ctypedef struct AVOutputFormat: 481 const char *name 482 const char *long_name 483 const char *mime_type 484 const char *extensions 485 AVCodecID audio_codec 486 AVCodecID video_codec 487 AVCodecID subtitle_codec 488 int flags #AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS, AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH, AVFMT_TS_NONSTRICT, AVFMT_TS_NEGATIVE More... 489 #AVCodecTag *const * codec_tag 490 int priv_data_size 491 int(*write_header)(AVFormatContext *) 492 int(*write_packet)(AVFormatContext *, AVPacket *pkt) 493 int(*write_trailer )(AVFormatContext *) 494 int(*interleave_packet)(AVFormatContext *, AVPacket *out, AVPacket *input, int flush) 495 int(*query_codec)(AVCodecID id, int std_compliance) 496 void(*get_output_timestamp )(AVFormatContext *s, int stream, int64_t *dts, int64_t *wall) 497 int(*control_message )(AVFormatContext *s, int type, void *data, size_t data_size) 498 int(*write_uncoded_frame )(AVFormatContext *, int stream_index, AVFrame **frame, unsigned flags) 499 #int(*get_device_list )(AVFormatContext *s, struct AVDeviceInfoList *device_list) 500 #int(*create_device_capabilities )(AVFormatContext *s, AVDeviceCapabilitiesQuery *caps) 501 #int(*free_device_capabilities )(AVFormatContext *s, AVDeviceCapabilitiesQuery *caps) 502 AVCodecID data_codec 503 int(*init)(AVFormatContext *) 504 void(*deinit)(AVFormatContext *) 505 int(*check_bitstream )(AVFormatContext *, const AVPacket *pkt) 506 507 void av_register_all() 508 AVOutputFormat *av_oformat_next (const AVOutputFormat *f) 509 int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename) 510 void avformat_free_context(AVFormatContext *s) 511 512 int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec) 513 int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par) 514 AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) 515 int avformat_write_header(AVFormatContext *s, AVDictionary **options) 516 int av_write_trailer(AVFormatContext *s) 517 int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) 518 int av_write_frame(AVFormatContext *s, AVPacket *pkt) 519 #void add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, AVCodecID codec_id) 520 521 AV_OPT_TYPES = { 522 AV_OPT_TYPE_FLAGS : "FLAGS", 523 AV_OPT_TYPE_INT : "INT", 524 AV_OPT_TYPE_INT64 : "INT64", 525 AV_OPT_TYPE_DOUBLE : "DOUBLE", 526 AV_OPT_TYPE_FLOAT : "FLOAT", 527 AV_OPT_TYPE_STRING : "STRING", 528 AV_OPT_TYPE_RATIONAL : "RATIONAL", 529 AV_OPT_TYPE_BINARY : "BINARY", 530 AV_OPT_TYPE_DICT : "DICT", 531 AV_OPT_TYPE_CONST : "CONST", 532 AV_OPT_TYPE_IMAGE_SIZE : "IMAGE_SIZE", 533 AV_OPT_TYPE_PIXEL_FMT : "PIXEL_FMT", 534 AV_OPT_TYPE_SAMPLE_FMT : "SAMPLE_FMT", 535 AV_OPT_TYPE_VIDEO_RATE : "VIDEO_RATE", 536 AV_OPT_TYPE_DURATION : "DURATION", 537 AV_OPT_TYPE_COLOR : "COLOR", 538 AV_OPT_TYPE_CHANNEL_LAYOUT : "CHANNEL_LAYOUT", 539 AV_OPT_TYPE_BOOL : "BOOL", 540 } 541 542 543 PKT_FLAGS = { 544 AV_PKT_FLAG_KEY : "KEY", 545 AV_PKT_FLAG_CORRUPT : "CORRUPT", 546 } 547 548 AVFMTCTX = { 549 AVFMTCTX_NOHEADER : "NOHEADER", 550 } 551 552 FMT_FLAGS = { 553 AVFMT_FLAG_GENPTS : "GENPTS", 554 AVFMT_FLAG_IGNIDX : "IGNIDX", 555 AVFMT_FLAG_NONBLOCK : "NONBLOCK", 556 AVFMT_FLAG_IGNDTS : "IGNDTS", 557 AVFMT_FLAG_NOFILLIN : "NOFILLIN", 558 AVFMT_FLAG_NOPARSE : "NOPARSE", 559 AVFMT_FLAG_NOBUFFER : "NOBUFFER", 560 AVFMT_FLAG_CUSTOM_IO : "CUSTOM_IO", 561 AVFMT_FLAG_DISCARD_CORRUPT : "DISCARD_CORRUPT", 562 AVFMT_FLAG_FLUSH_PACKETS : "FLUSH_PACKETS", 563 AVFMT_FLAG_BITEXACT : "BITEXACT", 564 AVFMT_FLAG_MP4A_LATM : "MP4A_LATM", 565 AVFMT_FLAG_SORT_DTS : "SORT_DTS", 566 AVFMT_FLAG_PRIV_OPT : "PRIV_OPT", 567 AVFMT_FLAG_KEEP_SIDE_DATA : "KEEP_SIDE_DATA", 568 AVFMT_FLAG_FAST_SEEK : "FAST_SEEK", 569 } 570 571 AVFMT = { 572 AVFMT_NOFILE : "NOFILE", 573 AVFMT_NEEDNUMBER : "NEEDNUMBER", 574 AVFMT_SHOW_IDS : "SHOW_IDS", 575 AVFMT_RAWPICTURE : "RAWPICTURE", 576 AVFMT_GLOBALHEADER : "GLOBALHEADER", 577 AVFMT_NOTIMESTAMPS : "NOTIMESTAMPS", 578 AVFMT_GENERIC_INDEX : "GENERIC_INDEX", 579 AVFMT_TS_DISCONT : "TS_DISCONT", 580 AVFMT_VARIABLE_FPS : "VARIABLE_FPS", 581 AVFMT_NODIMENSIONS : "NODIMENSIONS", 582 AVFMT_NOSTREAMS : "NOSTREAMS", 583 AVFMT_NOBINSEARCH : "NOBINSEARCH", 584 AVFMT_NOGENSEARCH : "NOGENSEARCH", 585 AVFMT_NO_BYTE_SEEK : "NO_BYTE_SEEK", 586 AVFMT_ALLOW_FLUSH : "ALLOW_FLUSH", 587 AVFMT_TS_NONSTRICT : "TS_NONSTRICT", 588 AVFMT_TS_NEGATIVE : "TS_NEGATIVE", 589 AVFMT_SEEK_TO_PTS : "SEEK_TO_PTS", 590 } 591 592 166 593 CAPS = { 167 594 CODEC_CAP_DRAW_HORIZ_BAND : "DRAW_HORIZ_BAND", 168 595 CODEC_CAP_DR1 : "DR1", … … 218 645 log("AV_PIX_FMT:") 219 646 print_nested_dict(ENUM_TO_FORMAT, print_fn=log.debug) 220 647 648 def flagscsv(flag_dict, value=0): 649 return csv([v for k,v in flag_dict.items() if k&value]) 650 651 652 def get_muxer_formats(): 653 av_register_all() 654 cdef AVOutputFormat *fmt = NULL 655 formats = {} 656 while True: 657 fmt = av_oformat_next(fmt) 658 if fmt==NULL: 659 break 660 name = fmt.name 661 long_name = fmt.long_name 662 formats[name] = long_name 663 return formats 664 log("AV Output Formats:") 665 print_nested_dict(get_muxer_formats(), print_fn=log.debug) 666 667 cdef AVOutputFormat* get_av_output_format(name): 668 cdef AVOutputFormat *fmt = NULL 669 while True: 670 fmt = av_oformat_next(fmt) 671 if fmt==NULL: 672 break 673 if name==fmt.name: 674 return fmt 675 return NULL 676 677 221 678 def get_version(): 222 679 return (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) 223 680 … … 231 688 # CODECS.append("vp9") 232 689 #if avcodec_find_encoder(AV_CODEC_ID_H265)!=NULL: 233 690 # CODECS.append("h265") 234 #if avcodec_find_encoder(AV_CODEC_ID_MPEG4)!=NULL:235 #CODECS.append("mpeg4")691 if avcodec_find_encoder(AV_CODEC_ID_MPEG4)!=NULL: 692 CODECS.append("mpeg4") 236 693 log("enc_ffmpeg CODECS=%s", csv(CODECS)) 237 694 238 695 cdef av_error_str(int errnum): … … 267 724 return { 268 725 "version" : get_version(), 269 726 "encodings" : get_encodings(), 727 "muxers" : get_muxer_formats(), 270 728 "buffer_api" : get_buffer_api_version(), 271 729 "formats" : f, 272 730 "generation" : generation.get(), … … 285 743 return ["YUV420P"] 286 744 287 745 746 GEN_TO_ENCODER = weakref.WeakValueDictionary() 747 748 749 cdef list_options(void *obj, const AVClass *av_class): 750 if av_class==NULL: 751 return 752 cdef const AVOption *option = <const AVOption*> av_class.option 753 options = [] 754 while option!=NULL: 755 oname = option.name 756 options.append(oname) 757 option = av_opt_next(obj, option) 758 log("%s options: %s", av_class.class_name, csv(options)) 759 cdef void *child = NULL 760 cdef const AVClass *child_class = NULL 761 while True: 762 child = av_opt_child_next(obj, child) 763 if child==NULL: 764 return 765 child_class = (<AVClass**> child)[0] 766 list_options(child, child_class) 767 768 769 cdef int write_packet(void *opaque, uint8_t *buf, int buf_size): 770 global GEN_TO_ENCODER 771 encoder = GEN_TO_ENCODER.get(<unsigned long> opaque) 772 log.warn("write_packet(%#x, %#x, %#x) encoder=%s", <unsigned long> opaque, <unsigned long> buf, buf_size, type(encoder)) 773 if not encoder: 774 log.error("Error: write_packet called for encoder %i!", <unsigned long> opaque) 775 return -1 776 return encoder.write_packet(<unsigned long> buf, buf_size) 777 778 cdef int64_t seek(void *opaque, int64_t offset, int whence): 779 global GEN_TO_ENCODER 780 encoder = GEN_TO_ENCODER.get(<unsigned long> opaque) 781 if not encoder: 782 log.error("Error: seek called for encoder %i!", <unsigned long> opaque) 783 return -1 784 return encoder.seek(offset, whence) 785 786 288 787 MAX_WIDTH, MAX_HEIGHT = 4096, 4096 289 788 def get_spec(encoding, colorspace): 290 789 assert encoding in get_encodings(), "invalid encoding: %s (must be one of %s" % (encoding, get_encodings()) … … 300 799 This wraps the AVCodecContext and its configuration, 301 800 """ 302 801 cdef AVCodec *codec 802 cdef AVStream *stream 803 cdef AVFormatContext *format_ctx 804 cdef unsigned char *buffer 805 cdef object buffers 806 cdef int64_t buf_len 807 cdef int64_t offset 303 808 cdef AVCodecContext *codec_ctx 304 809 cdef AVPixelFormat pix_fmt 305 810 cdef object src_format … … 309 814 cdef unsigned int width 310 815 cdef unsigned int height 311 816 cdef object encoding 817 cdef object muxer_format 312 818 cdef object file 313 819 314 820 cdef object __weakref__ 315 821 316 822 def init_context(self, unsigned int width, unsigned int height, src_format, dst_formats, encoding, int quality, int speed, scaling, options): #@DuplicatedSignature 823 cdef int r 317 824 global CODECS, generation 318 825 assert encoding in CODECS 319 826 assert src_format in get_input_colorspaces(encoding), "invalid colorspace: %s" % src_format … … 324 831 self.pix_fmt = FORMAT_TO_ENUM.get(src_format, AV_PIX_FMT_NONE) 325 832 if self.pix_fmt==AV_PIX_FMT_NONE: 326 833 raise Exception("invalid pixel format: %s", src_format) 834 self.buffers = [] 327 835 328 836 avcodec_register_all() 329 837 cdef AVCodecID CodecID … … 342 850 self.codec = avcodec_find_encoder(CodecID) 343 851 if self.codec==NULL: 344 852 raise Exception("codec %s not found!" % self.encoding) 345 log("%s: \"%s\", codec flags: %s", self.codec.name, self.codec.long_name, csv(v for k,v in CAPS.items() if (self.codec.capabilities & k)))853 log("%s: \"%s\", codec flags: %s", self.codec.name, self.codec.long_name, flagscsv(CAPS, self.codec.capabilities)) 346 854 347 #from here on, we have to call clean_encoder(): 855 #TODO: the muxer should be configurable 856 self.muxer_format = "mp4" #"mov", "f4v" 857 cdef int b_frames = 0 #int(options.get("b-frames")) 858 try: 859 self.init_encoder(b_frames) 860 except Exception as e: 861 log("init_encoder(%i) failed", b_frames, exc_info=True) 862 self.clean() 863 raise 864 else: 865 log("enc_ffmpeg.Encoder.init_context(%s, %s, %s) self=%s", self.width, self.height, self.src_format, self.get_info()) 866 867 def init_encoder(self, int b_frames): 868 global GEN_TO_ENCODER 869 cdef AVOutputFormat *oformat = get_av_output_format(self.muxer_format) 870 if oformat==NULL: 871 raise Exception("libavformat does not support %s" % self.muxer_format) 872 log("init_encoder() AVOutputFormat(%s)=%#x, flags=%s", self.muxer_format, <unsigned long> oformat, flagscsv(AVFMT, oformat.flags)) 873 if oformat.flags & AVFMT_ALLOW_FLUSH==0: 874 raise Exception("AVOutputFormat(%s) does not support flushing!" % self.muxer_format) 875 r = avformat_alloc_output_context2(&self.format_ctx, oformat, self.muxer_format, NULL) 876 if r!=0: 877 msg = av_error_str(r) 878 raise Exception("libavformat cannot allocate context: %s" % msg) 879 log("init_encoder() avformat_alloc_output_context2 returned %i, format context=%#x, flags=%s, ctx_flags=%s", r, <unsigned long> self.format_ctx, 880 flagscsv(FMT_FLAGS, self.format_ctx.flags), flagscsv(AVFMTCTX, self.format_ctx.ctx_flags)) 881 list_options(self.format_ctx, self.format_ctx.av_class) 882 883 cdef int64_t v = 0 884 r = av_opt_get_int(self.format_ctx, "movflags", AV_OPT_SEARCH_CHILDREN, &v) 885 if r==0: 886 log("movflags=%#x", v) 887 FF_MOV_FLAG_FRAGMENT = 1<<1 888 v |= FF_MOV_FLAG_FRAGMENT 889 r = av_opt_set_int(self.format_ctx, "movflags", v, AV_OPT_SEARCH_CHILDREN) 890 if r!=0: 891 log.error("Error: failed to set movflags") 892 log.error(" %s", av_error_str(r)) 893 894 cdef unsigned long gen = generation.increase() 895 GEN_TO_ENCODER[gen] = self 896 if SAVE_TO_FILE: 897 filename = SAVE_TO_FILE+"ffmpeg-"+self.encoding+"-"+str(gen)+".%s" % self.muxer_format 898 r = avio_open(&self.format_ctx.pb, filename, AVIO_FLAG_WRITE) 899 if r!=0: 900 msg = av_error_str(r) 901 raise Exception("libavformat cannot open file '%s': %s" % (filename, msg)) 902 log.info("init_encoder() saving %s stream to %s", self.encoding, filename) 903 else: 904 self.buf_len = 64*1024 905 self.buffer = <unsigned char*> av_malloc(self.buf_len) 906 if self.buffer==NULL: 907 raise Exception("failed to allocate %iKB of memory" % (self.buf_len//1024)) 908 self.format_ctx.pb = avio_alloc_context(self.buffer, self.buf_len, 1, <void *> gen, NULL, write_packet, NULL) 909 if self.format_ctx.pb==NULL: 910 raise Exception("libavformat failed to allocate io context") 911 #self.format_ctx.flags |= AVFMT_FLAG_CUSTOM_IO 912 log.info("init_encoder() saving %s stream to bitstream buffer %#x", self.encoding, <unsigned long> self.buffer) 913 914 self.stream = avformat_new_stream(self.format_ctx, NULL) 915 log("init_encoder() avformat_new_stream=%#x", <unsigned long> self.stream) 916 self.stream.id = 0 917 self.stream.time_base.num = 1 918 self.stream.time_base.den = 25 919 348 920 self.codec_ctx = avcodec_alloc_context3(self.codec) 349 921 if self.codec_ctx==NULL: 350 self.clean_encoder()351 922 raise Exception("failed to allocate codec context!") 352 923 353 cdef int b_frames = int(options.get("b-frames")) 924 #r = avcodec_parameters_to_context(self.codec_ctx, self.stream.codecpar) 925 #if r<0: 926 # raise Exception("could not copy context parameters %#x: %s" % (<unsigned long> self.stream.codecpar, av_error_str(r))) 354 927 #we need a framerate.. make one up: 355 928 self.codec_ctx.framerate.num = 1 356 929 self.codec_ctx.framerate.den = 25 … … 361 934 self.codec_ctx.has_b_frames = b_frames 362 935 self.codec_ctx.delay = 0 363 936 self.codec_ctx.gop_size = 1 364 self.codec_ctx.width = width365 self.codec_ctx.height = height937 self.codec_ctx.width = self.width 938 self.codec_ctx.height = self.height 366 939 self.codec_ctx.pix_fmt = self.pix_fmt 367 940 self.codec_ctx.thread_safe_callbacks = 1 368 941 self.codec_ctx.thread_type = 2 #FF_THREAD_SLICE: allow more than one thread per frame 369 942 self.codec_ctx.thread_count = 0 #auto 943 self.codec_ctx.flags |= CODEC_FLAG_GLOBAL_HEADER 370 944 self.codec_ctx.flags2 |= CODEC_FLAG2_FAST #may cause "no deblock across slices" - which should be fine 371 945 #av_opt_set(c->priv_data, "preset", "slow", 0) 372 cdef int r = avcodec_open2(self.codec_ctx, self.codec, NULL) 946 947 r = avcodec_open2(self.codec_ctx, self.codec, NULL) 948 if r!=0: 949 raise Exception("could not open %s encoder context: %s" % (self.encoding, av_error_str(r))) 950 951 r = avcodec_parameters_from_context(self.stream.codecpar, self.codec_ctx) 373 952 if r<0: 374 self.clean_encoder()375 raise Exception("could not open %s encoder context: %s" % (self.encoding, av_error_str(r))) 953 raise Exception("could not copy context parameters %#x: %s" % (<unsigned long> self.stream.codecpar, av_error_str(r))) 954 376 955 self.av_frame = av_frame_alloc() 377 956 if self.av_frame==NULL: 378 self.clean_encoder()379 957 raise Exception("could not allocate an AVFrame for encoding") 380 958 self.frames = 0 381 log("enc_ffmpeg.Encoder.init_context(%s, %s, %s) self=%s", width, height, src_format, self.get_info())382 gen = generation.increase()383 if SAVE_TO_FILE is not None:384 filename = SAVE_TO_FILE+"ffmpeg-"+self.encoding+"-"+str(gen)+".%s" % encoding385 self.file = open(filename, 'wb')386 log.info("saving %s stream to %s", encoding, filename)387 959 960 log("init_encoder() writing %s header", self.muxer_format) 961 r = avformat_write_header(self.format_ctx, NULL) 962 if r!=0: 963 msg = av_error_str(r) 964 raise Exception("libavformat failed to write header: %s" % msg) 965 388 966 def clean(self): 389 967 self.clean_encoder() 390 968 self.codec = NULL … … 395 973 self.width = 0 396 974 self.height = 0 397 975 self.encoding = "" 398 f = self.file 399 if f: 400 self.file = None 401 f.close() 976 self.buffers = [] 402 977 403 404 978 def clean_encoder(self): 405 cdef int r , i979 cdef int r 406 980 log("%s.clean_encoder()", self) 407 981 408 982 if self.av_frame!=NULL: … … 410 984 av_frame_free(&self.av_frame) 411 985 #redundant: self.frame = NULL 412 986 987 if self.format_ctx!=NULL: 988 if self.frames>0: 989 log("clean_encoder() writing trailer to stream") 990 av_write_trailer(self.format_ctx) 991 992 if SAVE_TO_FILE: 993 r = avio_close(self.format_ctx.pb) 994 if r<0: 995 log.error("Error closing IO context: %s", av_error_str(r)) 996 else: 997 if self.format_ctx.pb!=NULL: 998 av_free(self.format_ctx.pb) 999 self.format_ctx.pb = NULL 1000 1001 log("clean_encoder() freeing av format context %#x", <unsigned long> self.format_ctx) 1002 avformat_free_context(self.format_ctx) 1003 self.format_ctx = NULL 1004 1005 log("clean_encoder() freeing bitstream buffer %#x", <unsigned long> self.buffer) 1006 if self.buffer!=NULL: 1007 av_free(self.buffer) 1008 self.buffer = NULL 1009 413 1010 cdef unsigned long ctx_key #@DuplicatedSignature 414 1011 log("clean_encoder() freeing AVCodecContext: %#x", <unsigned long> self.codec_ctx) 415 1012 if self.codec_ctx!=NULL: … … 419 1016 log.error(" %s", av_error_str(r)) 420 1017 av_free(self.codec_ctx) 421 1018 self.codec_ctx = NULL 1019 1020 if self.buffers: 1021 import time 1022 filename = SAVE_TO_FILE+"ffmpeg-"+self.encoding+"-"+str(int(time.time()))+".%s" % self.muxer_format 1023 log("clean_encoder() saving %i buffers", len(self.buffers)) 1024 with open(filename, 'wb') as f: 1025 for b in self.buffers: 1026 f.write(b) 1027 422 1028 log("clean_encoder() done") 423 1029 424 1030 def __repr__(self): #@DuplicatedSignature … … 430 1036 info = { 431 1037 "version" : get_version(), 432 1038 "encoding" : self.encoding, 1039 "muxer" : self.muxer_format, 433 1040 "formats" : get_input_colorspaces(self.encoding), 434 1041 "type" : self.get_type(), 435 1042 "frames" : self.frames, … … 502 1109 istrides = image.get_rowstride() 503 1110 assert len(pixels)==3, "image pixels does not have 3 planes! (found %s)" % len(pixels) 504 1111 assert len(istrides)==3, "image strides does not have 3 values! (found %s)" % len(istrides) 505 1112 506 1113 #populate the avframe: 507 1114 for i in range(4): 508 1115 if i<3: … … 518 1125 self.av_frame.pts = self.frames+1 519 1126 self.av_frame.coded_picture_number = self.frames+1 520 1127 self.av_frame.display_picture_number = self.frames+1 521 if self.frames==0:522 self.av_frame.pict_type = AV_PICTURE_TYPE_I523 else:524 self.av_frame.pict_type = AV_PICTURE_TYPE_P1128 #if self.frames==0: 1129 # self.av_frame.pict_type = AV_PICTURE_TYPE_I 1130 #else: 1131 # self.av_frame.pict_type = AV_PICTURE_TYPE_P 525 1132 #self.av_frame.quality = 1 526 1133 frame = self.av_frame 527 1134 else: … … 560 1167 raise Exception(av_error_str(ret)) 561 1168 if ret>0: 562 1169 free(avpkt.data) 563 self.log_ error(image, ret, options, "no stream")1170 self.log_av_error(image, ret, options, "no stream") 564 1171 raise Exception("no stream") 565 log("avcodec_receive_packet returned %#x bytes of data", avpkt.size) 1172 log("avcodec_receive_packet returned %#x bytes of data, flags: %s", avpkt.size, flagscsv(PKT_FLAGS, avpkt.flags)) 1173 if avpkt.flags & AV_PKT_FLAG_CORRUPT: 1174 free(avpkt.data) 1175 self.log_error(image, "packet", options, "av packet is corrupt") 1176 raise Exception("av packet is corrupt") 566 1177 packet_data = avpkt.data[:avpkt.size] 567 1178 bufs.append(packet_data) 568 if self.file and packet_data: 569 self.file.write(packet_data) 570 self.file.flush() 1179 1180 if SAVE_TO_FILE or True: 1181 avpkt.stream_index = self.stream.index 1182 r = av_write_frame(self.format_ctx, &avpkt) 1183 if ret<0: 1184 free(avpkt.data) 1185 self.log_av_error(image, ret, options) 1186 raise Exception(av_error_str(ret)) 1187 r = av_write_frame(self.format_ctx, NULL) 1188 if ret<0: 1189 free(avpkt.data) 1190 self.log_av_error(image, ret, options) 1191 raise Exception(av_error_str(ret)) 571 1192 av_packet_unref(&avpkt) 572 1193 free(avpkt.data) 573 1194 self.frames += 1 … … 581 1202 self.clean() 582 1203 return v 583 1204 1205 def write_packet(self, unsigned long buf, int buf_size): 1206 log.warn("write_packet(%#x, %#x) buffer=%#x", <unsigned long> buf, buf_size, <unsigned long> self.buffer) 1207 cdef uint8_t *cbuf = <uint8_t*> buf 1208 #if buf!=self.buffer: 1209 # log.error("Error: write_packet buffer mismatch") 1210 # log.error(" expected %#x but received %#x", <unsigned long> self.buffer, <unsigned long> buf) 1211 if self.offset+buf_size>self.buf_len: 1212 log.error("Error: writing packet would overflow the buffer") 1213 log.error(" current offset=%#x, data size=%#x, buffer size=%#x", self.offset, buf_size, self.buf_len) 1214 return -1 1215 memcpy(self.buffer + self.offset, cbuf, buf_size) 1216 self.offset += buf_size 1217 log("write_packet(%#x, %#x) new offset=%#x", <unsigned long> buf, buf_size, self.offset) 1218 buffer = cbuf[:buf_size] 1219 self.buffers.append(buffer) 1220 return buf_size 584 1221 1222 def seek(self, int64_t offset, int whence): 1223 global SEEKS 1224 if whence==SEEK_SET: 1225 if offset<0: 1226 log.warn("Warning: invalid SEEK_SET offset: %i", offset) 1227 offset = 0 1228 elif offset>=self.buf_len: 1229 log.warn("Warning: invalid SEEK_SET offset: %i", offset) 1230 return -1 1231 self.offset = offset 1232 elif whence==SEEK_CUR: 1233 if self.offset+offset<0: 1234 log.warn("Warning: invalid SEEK_CUR %i+%i clipped to 0", self.offset, offset) 1235 self.offset = 0 1236 elif self.offset+offset>=self.buf_len: 1237 log.warn("Warning: invalid SEEK_CUR %i+%i clipped to %i", self.offset, offset, self.buf_len-1) 1238 self.offset = self.buf_len-1 1239 else: 1240 self.offset += offset 1241 elif whence==SEEK_END: 1242 log.warn("Warning: SEEK_END not supported") 1243 return -1 1244 else: 1245 log.error("Error: unknowm seek whence value %i", whence) 1246 return -1 1247 log("seek(%i, %s)=%i", offset, SEEKS.get(whence, whence), self.offset) 1248 return self.offset 1249 1250 585 1251 def selftest(full=False): 586 1252 global CODECS 587 1253 from xpra.codecs.codec_checks import testencoder