Ticket #40464: libquicktime-cvs.diff
File libquicktime-cvs.diff, 71.5 KB (added by mojca (Mojca Miklavec), 11 years ago) |
---|
-
configure.ac
9 9 10 10 USER_CFLAGS=$CFLAGS 11 11 12 AM_CONFIG_HEADER(config.h) 12 dnl AM_CONFIG_HEADER(config.h) 13 AC_CONFIG_HEADERS(config.h) 13 14 14 15 AC_CANONICAL_HOST 15 16 AM_MAINTAINER_MODE … … 39 40 dnl Libquicktime codec API version 40 41 dnl 41 42 42 LQT_CODEC_API_VERSION="1 2"43 LQT_CODEC_API_VERSION="13" 43 44 44 45 AH_TEMPLATE([HAVE_GPL], [Enable GPL code]) 45 46 AH_TEMPLATE([LQT_CODEC_API_VERSION], -
include/colorspace_macros.h
372 372 /* YUV (10 bit) -> 8 */ 373 373 374 374 #define YUV_10_TO_RGB_24(y,u,v,r,g,b) \ 375 i_tmp=(yj_16_to_rgb * (y-0x40) + vj_16_to_r * (v-0x200))>>18; \376 r = RECLIP_8(i_tmp);\377 i_tmp=(yj_16_to_rgb * (y-0x40) + uj_16_to_g * (u-0x200)+ vj_16_to_g * (v-0x200))>>18; \378 g = RECLIP_8(i_tmp);\379 i_tmp=(yj_16_to_rgb * (y-0x40) + uj_16_to_b * (u-0x200))>>18; \380 b = RECLIP_8(i_tmp);375 i_tmp=(y_16_to_rgb * (y-0x40) + v_16_to_r * (v-0x200))>>18; \ 376 r = RECLIP_8(i_tmp);\ 377 i_tmp=(y_16_to_rgb * (y-0x40) + u_16_to_g * (u-0x200)+ v_16_to_g * (v-0x200))>>18; \ 378 g = RECLIP_8(i_tmp);\ 379 i_tmp=(y_16_to_rgb * (y-0x40) + u_16_to_b * (u-0x200))>>18; \ 380 b = RECLIP_8(i_tmp); 381 381 382 382 #define YUVJ_10_TO_RGB_24(y,u,v,r,g,b) \ 383 383 i_tmp=(yj_16_to_rgb * y + vj_16_to_r * (v-0x200))>>18; \ -
include/lqt_funcprotos.h
1015 1015 void quicktime_read_stss(quicktime_t *file, quicktime_stss_t *stss); 1016 1016 void quicktime_write_stss(quicktime_t *file, quicktime_stss_t *stss); 1017 1017 1018 /* stps.c */ 1019 1020 void quicktime_stps_init(quicktime_stps_t *stps); 1021 void quicktime_stps_delete(quicktime_stps_t *stps); 1022 void quicktime_stps_dump(quicktime_stps_t *stps); 1023 void quicktime_read_stps(quicktime_t *file, quicktime_stps_t *stps); 1024 void quicktime_write_stps(quicktime_t *file, quicktime_stps_t *stps); 1025 1018 1026 /* stsz.c */ 1019 1027 1020 1028 void quicktime_stsz_init(quicktime_stsz_t *stsz); … … 1033 1041 long sample_size); 1034 1042 void quicktime_stsz_init_timecode(quicktime_stsz_t *stsz); 1035 1043 1044 /* sdtp.c */ 1045 1046 void quicktime_sdtp_init(quicktime_sdtp_t *sdtp); 1047 void quicktime_sdtp_delete(quicktime_sdtp_t *sdtp); 1048 void quicktime_sdtp_dump(quicktime_sdtp_t *sdtp); 1049 void quicktime_read_sdtp(quicktime_t *file, quicktime_sdtp_t *sdtp, long num_entries); 1050 void quicktime_write_sdtp(quicktime_t *file, quicktime_sdtp_t *sdtp); 1051 1036 1052 /* stts.c */ 1037 1053 1038 1054 void quicktime_stts_init(quicktime_stts_t *stts); … … 1462 1478 int quicktime_codecs_flush(quicktime_t *file); 1463 1479 1464 1480 LQT_EXTERN void lqt_write_frame_header(quicktime_t * file, int track, 1465 int pic_num1, int64_t pic_pts, int keyframe); 1481 int pic_num1, int64_t pic_pts, 1482 enum LqtKeyFrame keyframe); 1466 1483 1467 1484 LQT_EXTERN void lqt_write_frame_footer(quicktime_t * file, int track); 1468 1485 … … 1480 1497 /* workarounds.c */ 1481 1498 1482 1499 int64_t quicktime_add3(int64_t a, int64_t b, int64_t c); 1500 1501 1502 /* bframe_detector.c */ 1503 1504 LQT_EXTERN void quicktime_init_bframe_detector(quicktime_bframe_detector* ctx, quicktime_video_map_t* vtrack); 1505 LQT_EXTERN int quicktime_is_bframe(quicktime_bframe_detector* ctx, int64_t frame); -
include/quicktime/lqt.h
1056 1056 * \param file A quicktime handle 1057 1057 * \param row_pointers Frame (see \ref lqt_rows_alloc) 1058 1058 * \param track Track index (starting with 0) 1059 * \returns 0 on success and a non-zero value on failure. 1059 1060 * 1060 1061 * Decode one video frame and increment the interal frame pointer. 1061 1062 * To get the presentation timestamp for this frame, call -
include/quicktime/qtprivate.h
592 592 quicktime_stss_table_t *table; 593 593 } quicktime_stss_t; 594 594 595 /* partial sync sample */ 596 typedef struct 597 { 598 long sample; 599 } quicktime_stps_table_t; 600 601 typedef struct 602 { 603 int version; 604 long flags; 605 long total_entries; 606 long entries_allocated; 607 quicktime_stps_table_t *table; 608 } quicktime_stps_t; 595 609 596 610 /* sample to chunk */ 597 611 typedef struct … … 629 643 quicktime_stsz_table_t *table; 630 644 } quicktime_stsz_t; 631 645 646 /* sample dependency table */ 647 typedef struct 648 { 649 int version; 650 long flags; 651 long total_entries; 652 long entries_allocated; 653 uint8_t *table; 654 } quicktime_sdtp_t; 632 655 633 656 /* chunk offset */ 634 657 typedef struct … … 656 679 quicktime_stsd_t stsd; 657 680 quicktime_stts_t stts; 658 681 quicktime_stss_t stss; 682 quicktime_stps_t stps; 659 683 quicktime_stsc_t stsc; 660 684 quicktime_stsz_t stsz; 685 quicktime_sdtp_t sdtp; 661 686 quicktime_stco_t stco; 662 687 quicktime_ctts_t ctts; 663 688 int has_ctts; … … 1357 1382 1358 1383 } quicktime_audio_map_t; 1359 1384 1385 1386 enum LqtKeyFrame { 1387 LQT_NO_KEY_FRAME = 0, 1388 LQT_FULL_KEY_FRAME = 1, 1389 LQT_PARTIAL_KEY_FRAME = 2 /* Corresponds to an I-frame in an open GOP. */ 1390 }; 1391 1392 1360 1393 typedef struct 1361 1394 { 1362 1395 quicktime_trak_t *track; … … 1421 1454 1422 1455 /* For encoding */ 1423 1456 quicktime_atom_t chunk_atom; 1424 intkeyframe;1457 enum LqtKeyFrame keyframe; 1425 1458 1426 1459 lqt_compression_info_t ci; 1460 1461 /* 1 if encoding, 0 if decoding. */ 1462 int do_encode; 1427 1463 1428 1464 } quicktime_video_map_t; 1429 1465 … … 1680 1716 1681 1717 }; 1682 1718 1719 1720 typedef struct 1721 { 1722 int64_t frame; 1723 long ctts_entry_idx; 1724 long sample_within_entry; 1725 quicktime_ctts_t *ctts; 1726 } quicktime_bframe_detector; 1727 1683 1728 #endif -
include/quicktime/quicktime.h
1098 1098 1099 1099 /* One keyframe table for each track */ 1100 1100 long quicktime_get_keyframe_before(quicktime_t *file, long frame, int track); 1101 long quicktime_get_partial_keyframe_before(quicktime_t *file, long frame, int track); 1101 1102 void quicktime_insert_keyframe(quicktime_t *file, long frame, int track); 1103 void quicktime_insert_partial_keyframe(quicktime_t *file, long frame, int track); 1102 1104 /* Track has keyframes */ 1103 1105 int quicktime_has_keyframes(quicktime_t *file, int track); 1104 1106 1107 /* Sample dependencies for long-GOP formats. */ 1108 void quicktime_insert_sdtp_entry(quicktime_t *file, long frame, int track, uint8_t flags); 1109 1105 1110 /* ===================== Access to built in codecs follows. */ 1106 1111 1107 1112 /* If the codec for this track is supported in the library return 1. */ -
plugins/audiocodec/pcm.c
1053 1053 { 1054 1054 case 8: 1055 1055 atrack->block_align = atrack->channels; 1056 atrack->sample_format = LQT_SAMPLE_ UINT8;1056 atrack->sample_format = LQT_SAMPLE_INT8; 1057 1057 codec->encode = encode_8; 1058 1058 codec->decode = decode_8; 1059 1059 break; -
plugins/faac/faac.c
52 52 int bitrate; 53 53 int quality; 54 54 int object_type; 55 int priming_delay; 55 56 } quicktime_faac_codec_t; 56 57 57 58 … … 80 81 81 82 imax = codec->sample_buffer_size * track_map->channels; 82 83 83 if(!num_samples && (codec->encoder_delay < 0))84 if(!num_samples && (codec->encoder_delay < -FAAC_PRIMING_DELAY)) 84 85 return 0; 85 86 86 87 for(i = 0; i < imax; i++) … … 116 117 lqt_start_audio_vbr_frame(file, track); 117 118 result = !quicktime_write_data(file, codec->chunk_buffer, 118 119 bytes_encoded); 119 if(codec->encoder_delay < 0)120 if(codec->encoder_delay < -FAAC_PRIMING_DELAY) 120 121 { 121 122 lqt_finish_audio_vbr_frame(file, track, codec->samples_per_frame + 122 codec->encoder_delay );123 codec->encoder_delay + FAAC_PRIMING_DELAY); 123 124 } 124 125 else 125 126 lqt_finish_audio_vbr_frame(file, track, codec->samples_per_frame); … … 205 206 { 206 207 int samples_read; 207 208 int samples_to_copy; 209 int priming_delay = 0; 208 210 209 211 faacEncConfigurationPtr enc_config; 210 212 unsigned long input_samples; … … 255 257 #endif 256 258 codec->chunk_buffer_size = output_bytes; 257 259 codec->chunk_buffer = malloc(codec->chunk_buffer_size); 260 261 if(codec->priming_delay > FAAC_PRIMING_DELAY) 262 priming_delay = codec->priming_delay - FAAC_PRIMING_DELAY; 258 263 259 264 codec->initialized = 1; 260 265 … … 276 281 277 282 while(samples_read < samples) 278 283 { 284 /* Add priming delay */ 285 if(priming_delay >= codec->samples_per_frame) 286 { 287 memset(codec->sample_buffer, 0, 288 codec->samples_per_frame * track_map->channels * sizeof(float)); 289 codec->sample_buffer_size = codec->samples_per_frame; 290 priming_delay -= codec->samples_per_frame; 291 } 292 else if(priming_delay > 0) 293 { 294 memset(codec->sample_buffer, 0, 295 priming_delay * track_map->channels * sizeof(float)); 296 codec->sample_buffer_size = priming_delay; 297 priming_delay = 0; 298 } 279 299 /* Put samples into sample buffer */ 280 300 281 301 samples_to_copy = codec->samples_per_frame - codec->sample_buffer_size; 282 302 if(samples_read + samples_to_copy > samples) 283 303 samples_to_copy = samples - samples_read; 284 304 285 memcpy(codec->sample_buffer + 286 track_map->channels * codec->sample_buffer_size, 287 input + samples_read * track_map->channels, 288 samples_to_copy * track_map->channels * sizeof(float)); 289 290 codec->sample_buffer_size += samples_to_copy; 291 samples_read += samples_to_copy; 305 if(samples_to_copy > 0) 306 { 307 memcpy(codec->sample_buffer + 308 track_map->channels * codec->sample_buffer_size, 309 input + samples_read * track_map->channels, 310 samples_to_copy * track_map->channels * sizeof(float)); 311 312 codec->sample_buffer_size += samples_to_copy; 313 samples_read += samples_to_copy; 314 } 292 315 293 316 /* Encode one frame, possibly starting a new audio chunk */ 294 317 if(codec->sample_buffer_size == codec->samples_per_frame) … … 312 335 { 313 336 quicktime_audio_map_t *track_map = &file->atracks[track]; 314 337 quicktime_faac_codec_t *codec = track_map->codec->priv; 315 338 316 339 if(!strcasecmp(key, "faac_bitrate")) 317 340 codec->bitrate = *(int*)value; 318 341 else if(!strcasecmp(key, "faac_quality")) … … 328 351 else if(!strcmp((char*)value, "LTP")) 329 352 codec->object_type = LTP; 330 353 } 354 else if(!strcasecmp(key, "faac_priming_delay")) 355 codec->priming_delay = *(int*)value; 331 356 return 0; 332 357 } 333 358 … … 404 429 405 430 codec->bitrate = 0; 406 431 codec->quality = 100; 432 codec->priming_delay = 2112; 407 433 408 434 if(!atrack) 409 435 return; -
plugins/faac/lqt_faac.c
39 39 .val_default = { .val_int = 0 } 40 40 }, 41 41 { 42 .name = " quality",42 .name = "faac_quality", 43 43 .real_name = TRS("VBR Quality"), 44 44 .type = LQT_PARAMETER_INT, 45 45 .val_min = { .val_int = 10 }, … … 47 47 .val_default = { .val_int = 100 }, 48 48 }, 49 49 { 50 .name = " object_type",50 .name = "faac_object_type", 51 51 .real_name = TRS("Object type"), 52 52 .type = LQT_PARAMETER_STRINGLIST, 53 53 .val_default = { .val_string = "Low" }, … … 57 57 TRS("LTP"), 58 58 (char*)0 }, 59 59 }, 60 { 61 .name = "faac_priming_delay", 62 .real_name = TRS("Priming delay (samples)"), 63 .type = LQT_PARAMETER_INT, 64 .val_min = { .val_int = FAAC_PRIMING_DELAY }, 65 .val_default = { .val_int = 2112 }, 66 }, 60 67 { /* End of parameters */ } 61 68 }; 62 69 -
plugins/faac/qtfaac.h
22 22 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 23 *******************************************************************************/ 24 24 25 #define FAAC_PRIMING_DELAY 1024 26 25 27 void quicktime_init_codec_faac(quicktime_codec_t * codec, 26 28 quicktime_audio_map_t *atrack, 27 29 quicktime_video_map_t *vtrack); -
plugins/ffmpeg/audio.c
45 45 #define ENCODE_AUDIO 1 46 46 #endif 47 47 48 #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE 49 /* from libavcodec/avcodec.h dated Dec 23 2012 */ 50 #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio 51 #endif 52 48 53 /* The following code was ported from gmerlin_avdecoder (http://gmerlin.sourceforge.net) */ 49 54 50 55 /* MPEG Audio header parsing code */ -
plugins/ffmpeg/lqt_ffmpeg.c
53 53 #define CODEC_TYPE_NB AVMEDIA_TYPE_NB 54 54 #endif 55 55 56 #if LIBAVCODEC_VERSION_INT > ((53<<16)|(17<<8)|0) 57 #define HAVE_PRORES_SUPPORT 58 #endif 59 56 60 57 61 #define ENCODE_PARAM_AUDIO \ 58 62 { \ … … 198 202 .val_default = { .val_int = 1 } \ 199 203 } 200 204 205 #define ENCODE_PARAM_PRORES \ 206 { \ 207 .name = "prores_profile", \ 208 .real_name = TRS("ProRes profile"), \ 209 .type = LQT_PARAMETER_STRINGLIST, \ 210 .val_default = { .val_string = "Standard" }, \ 211 .stringlist_options = (char *[]){ "HQ", "Standard", "LT", "Proxy", \ 212 (char *)0 } \ 213 } 214 201 215 #define DECODE_PARAM_AUDIO 202 216 203 217 #define DECODE_PARAM_VIDEO \ 204 PARAM_FLAG_GRAY 218 PARAM_FLAG_GRAY, \ 219 PARAM_THREAD_COUNT 220 205 221 206 222 static lqt_parameter_info_static_t encode_parameters_mpeg4[] = { 207 223 ENCODE_PARAM_VIDEO_FRAMETYPES_IPB, … … 292 308 }; 293 309 294 310 static lqt_parameter_info_static_t encode_parameters_imx[] = { 311 PARAM_THREAD_COUNT, 295 312 ENCODE_PARAM_IMX, 296 313 { /* End of parameters */ } 297 314 }; 298 315 316 static lqt_parameter_info_static_t encode_parameters_dnxhd[] = { 317 PARAM_THREAD_COUNT, 318 { /* End of parameters */ } 319 }; 320 321 static lqt_parameter_info_static_t encode_parameters_xdcam_hd422[] = { 322 PARAM_THREAD_COUNT, 323 { /* End of parameters */ } 324 }; 325 326 static lqt_parameter_info_static_t encode_parameters_prores[] = { 327 PARAM_THREAD_COUNT, 328 ENCODE_PARAM_PRORES, 329 { /* End of parameters */ } 330 }; 331 299 332 300 333 static lqt_parameter_info_static_t encode_parameters_audio[] = { 301 334 ENCODE_PARAM_AUDIO, … … 684 717 .index = -1, 685 718 .encoder = NULL, 686 719 .decoder = NULL, 720 .decode_parameters = decode_parameters_video, 687 721 .short_name = "rle", 688 722 .name = TRS("FFMPEG RLE"), 689 723 .fourccs = { "rle ", (char *)0 }, … … 697 731 .index = -1, 698 732 .encoder = NULL, 699 733 .decoder = NULL, 734 .decode_parameters = decode_parameters_video, 700 735 .short_name = "wrle", 701 736 .name = TRS("FFMPEG Microsoft RLE"), 702 737 .fourccs = { "WRLE", (char *)0 }, … … 806 841 .encoder = NULL, 807 842 .decoder = NULL, 808 843 .decode_parameters = decode_parameters_video, 844 .encode_parameters = encode_parameters_dnxhd, 809 845 .image_sizes = image_sizes_dnxhd, 810 846 .short_name = "dnxhd", 811 847 .name = TRS("FFMPEG dnxhd"), … … 826 862 .image_sizes = image_sizes_imx, 827 863 .short_name = "imx", 828 864 .name = TRS("FFMPEG IMX"), 829 .fourccs = { "mx3p", "mx3n", "mx4p", "mx4n", "mx5p", "mx5n", (char *)0 },865 .fourccs = { "mx3p", "mx3n", "mx4p", "mx4n", "mx5p", "mx5n", "AVmp", (char *)0 }, 830 866 .wav_ids = { LQT_WAV_ID_NONE }, 831 867 .compatibility_flags = LQT_FILE_QT_OLD | LQT_FILE_QT, 832 868 .do_encode = 1, 833 869 .compression_id = LQT_COMPRESSION_D10 834 870 }, 871 { 872 .id = CODEC_ID_MPEG2VIDEO, 873 .index = -1, 874 .encoder = NULL, 875 .decoder = NULL, 876 .decode_parameters = decode_parameters_video, 877 .short_name = "xdcam_hd", 878 .name = TRS("FFMPEG XDCAM HD"), 879 .fourccs = { 880 "xdv1", "xdv2", "xdv3", "xdv4", "xdv5", "xdv6", "xdv7", "xdv8", 881 "xdv9", "xdva", (char *)0 }, 882 .wav_ids = { LQT_WAV_ID_NONE }, 883 .compatibility_flags = LQT_FILE_QT 884 }, 885 { 886 .id = CODEC_ID_MPEG2VIDEO, 887 .index = -1, 888 .encoder = NULL, 889 .decoder = NULL, 890 .decode_parameters = decode_parameters_video, 891 .short_name = "xdcam_ex", 892 .name = TRS("FFMPEG XDCAM EX"), 893 .fourccs = { "xdvb", "xdvc", "xdvd", "xdve", "xdvf", (char *)0 }, 894 .wav_ids = { LQT_WAV_ID_NONE }, 895 .compatibility_flags = LQT_FILE_QT 896 }, 897 { 898 .id = CODEC_ID_MPEG2VIDEO, 899 .index = -1, 900 .encoder = NULL, 901 .decoder = NULL, 902 .decode_parameters = decode_parameters_video, 903 .encode_parameters = encode_parameters_xdcam_hd422, 904 .short_name = "xdcam_hd422", 905 .name = TRS("FFMPEG XDCAM HD422"), 906 .fourccs = { 907 "xd54", "xd55", "xd59", "xd5a", "xd5b", "xd5c", "xd5d", "xd5e", "xd5f", 908 (char *)0 }, 909 .wav_ids = { LQT_WAV_ID_NONE }, 910 .compatibility_flags = LQT_FILE_QT, 911 .do_encode = 1, 912 .encoding_colormodels = (int[]){ BC_YUV422P, LQT_COLORMODEL_NONE } 913 }, 914 #ifdef HAVE_PRORES_SUPPORT 915 { 916 .id = CODEC_ID_PRORES, 917 .index = -1, 918 .encoder = NULL, 919 .decoder = NULL, 920 .decode_parameters = decode_parameters_video, 921 .encode_parameters = encode_parameters_prores, 922 .short_name = "prores", 923 .name = TRS("FFMPEG ProRes"), 924 .fourccs = { "apch", "apcn", "apcs", "apco", (char *)0 }, 925 .wav_ids = { LQT_WAV_ID_NONE }, 926 .compatibility_flags = LQT_FILE_QT, 927 .do_encode = 1, 928 .encoding_colormodels = (int[]){ BC_YUV422P10, LQT_COLORMODEL_NONE } 929 }, 930 #endif 835 931 }; 836 932 837 933 /* Audio */ … … 955 1051 for(i = 0; i < NUMMAPS_V; i++) 956 1052 { 957 1053 if(codecidmap_v[i].do_encode) 958 codecidmap_v[i].encoder = avcodec_find_encoder(codecidmap_v[i].id); 1054 { 1055 #ifdef HAVE_PRORES_SUPPORT 1056 // FFMpeg has 2 different ProRes encoders, so try the better one first. 1057 if(codecidmap_v[i].id == CODEC_ID_PRORES) 1058 { 1059 // In newer versions it's called prores_ks. It used to be called prores_kostya 1060 codecidmap_v[i].encoder = avcodec_find_encoder_by_name("prores_ks"); 1061 if(!codecidmap_v[i].encoder) 1062 codecidmap_v[i].encoder = avcodec_find_encoder_by_name("prores_kostya"); 1063 } 1064 1065 if(!codecidmap_v[i].encoder) 1066 #endif 1067 codecidmap_v[i].encoder = avcodec_find_encoder(codecidmap_v[i].id); 1068 } 959 1069 codecidmap_v[i].decoder = avcodec_find_decoder(codecidmap_v[i].id); 960 1070 961 1071 if(codecidmap_v[i].encoder || codecidmap_v[i].decoder) -
plugins/ffmpeg/params.c
101 101 } \ 102 102 } 103 103 104 #define PARAM_DICT_INT(name, dict_name) \ 105 { \ 106 if(!strcasecmp(name, key)) \ 107 { \ 108 char buf[128]; \ 109 snprintf(buf, sizeof(buf), "%d", *(int*)value); \ 110 av_dict_set(options, dict_name, buf, 0); \ 111 found = 1; \ 112 } \ 113 } 114 104 115 #define PARAM_DICT_FLAG(name, dict_name) \ 105 116 { \ 106 117 if(!strcasecmp(name, key)) \ … … 202 213 PARAM_INT("ff_max_b_frames",max_b_frames); 203 214 PARAM_FLOAT("ff_b_quant_factor",b_quant_factor); 204 215 PARAM_INT("ff_b_frame_strategy",b_frame_strategy); 216 217 #if LIBAVCODEC_VERSION_MAJOR >= 55 218 PARAM_DICT_INT("ff_luma_elim_threshold","luma_elim_threshold"); 219 PARAM_DICT_INT("ff_chroma_elim_threshold","chroma_elim_threshold"); 220 #else 205 221 PARAM_INT("ff_luma_elim_threshold",luma_elim_threshold); 206 222 PARAM_INT("ff_chroma_elim_threshold",chroma_elim_threshold); 223 #endif 224 207 225 PARAM_INT("ff_strict_std_compliance",strict_std_compliance); 208 226 PARAM_QP2LAMBDA("ff_b_quant_offset",b_quant_offset); 209 227 PARAM_INT("ff_rc_min_rate",rc_min_rate); … … 241 259 PARAM_QP2LAMBDA("ff_lmax", lmax); 242 260 PARAM_INT("ff_noise_reduction",noise_reduction); 243 261 PARAM_INT_SCALE("ff_rc_initial_buffer_occupancy",rc_initial_buffer_occupancy,1000); 262 263 #if LIBAVCODEC_VERSION_MAJOR >= 55 264 PARAM_DICT_INT("ff_inter_threshold","inter_threshold"); 265 PARAM_DICT_INT("ff_quantizer_noise_shaping","quantizer_noise_shaping"); 266 #else 244 267 PARAM_INT("ff_inter_threshold",inter_threshold); 245 268 PARAM_INT("ff_quantizer_noise_shaping",quantizer_noise_shaping); 269 #endif 270 246 271 PARAM_INT("ff_thread_count",thread_count); 247 272 PARAM_INT("ff_me_threshold",me_threshold); 248 273 PARAM_INT("ff_mb_threshold",mb_threshold); … … 272 297 PARAM_FLAG("ff_flag_bitexact",CODEC_FLAG_BITEXACT); 273 298 PARAM_FLAG("ff_flag_ac_pred",CODEC_FLAG_AC_PRED); 274 299 // PARAM_FLAG("ff_flag_h263p_umv",CODEC_FLAG_H263P_UMV); // Unused 300 301 #if LIBAVCODEC_VERSION_MAJOR >= 55 302 PARAM_DICT_FLAG("ff_flag_cbp_rd","cbp_rd"); 303 PARAM_DICT_FLAG("ff_flag_qp_rd","qp_rd"); 304 PARAM_DICT_FLAG("ff_flag2_strict_gop","strict_gop"); 305 #else 275 306 PARAM_FLAG("ff_flag_cbp_rd",CODEC_FLAG_CBP_RD); 276 307 PARAM_FLAG("ff_flag_qp_rd",CODEC_FLAG_QP_RD); 308 PARAM_FLAG2("ff_flag2_strict_gop",CODEC_FLAG2_STRICT_GOP); 309 #endif 277 310 278 311 #if LIBAVCODEC_VERSION_MAJOR >= 54 279 312 PARAM_DICT_FLAG("ff_flag_h263p_aiv", "aiv"); … … 288 321 PARAM_FLAG("ff_flag_loop_filter",CODEC_FLAG_LOOP_FILTER); 289 322 PARAM_FLAG("ff_flag_closed_gop",CODEC_FLAG_CLOSED_GOP); 290 323 PARAM_FLAG2("ff_flag2_fast",CODEC_FLAG2_FAST); 291 PARAM_FLAG2("ff_flag2_strict_gop",CODEC_FLAG2_STRICT_GOP);292 324 PARAM_ENUM("ff_coder_type",coder_type,coder_type); 293 325 294 326 } -
plugins/ffmpeg/video.c
43 43 #define PIX_FMT_YUV422P10_OR_DUMMY -1234 44 44 #endif 45 45 46 #if LIBAVCODEC_VERSION_INT > ((53<<16)|(17<<8)|0) 47 #define HAVE_PRORES_SUPPORT 48 #endif 49 46 50 #if LIBAVCODEC_VERSION_INT >= ((54<<16)|(1<<8)|0) 47 51 #define ENCODE_VIDEO2 1 48 52 #else 49 53 #define ENCODE_VIDEO 1 50 54 #endif 51 55 56 static const struct 57 { 58 const char* fourcc; 59 60 /* There are two different ProRes encoders in FFMpeg. One of them 61 only accepts numeric profile values, while the other one also 62 accepts profile names. Fortunately, they do agree on numeric values. */ 63 const char* ffmpeg_profile; 64 65 const char* lqt_name; 66 } lqt_prores_profiles[] = { 67 { "apco", "0", "Proxy" }, 68 { "apcs", "1", "LT" }, 69 { "apcn", "2", "Standard" }, 70 { "apch", "3", "HQ" } 71 }; 72 52 73 /* We keep the numeric values the same as in the ACLR atom. 53 74 The interpretation of values is based on trial and error. */ 54 75 enum AvidYuvRange … … 95 116 enum PixelFormat reinterpret_pix_fmt; 96 117 97 118 int is_imx; 119 int is_xdcam_hd422; 98 120 int y_offset; 121 int prores_profile; // Index into lqt_prores_profiles, for encoding only. 99 122 100 123 #if LIBAVCODEC_VERSION_MAJOR < 54 101 124 AVPaletteControl palette; … … 129 152 130 153 /* Stuff for compressed H.264 reading */ 131 154 int nal_size_length; 155 156 quicktime_bframe_detector bframe_detector; 157 158 /* lqt_pts = ffmpeg_pts * pts_factor */ 159 int encoding_pts_factor; 160 132 161 } quicktime_ffmpeg_video_codec_t; 133 162 134 163 /* ffmpeg <-> libquicktime colormodels */ … … 291 320 *p += 4; 292 321 } 293 322 323 static uint8_t generate_sdtp_flags_mpeg2(long frame, const AVCodecContext* avctx) 324 { 325 unsigned flags = 0; 326 327 switch(avctx->coded_frame->pict_type) 328 { 329 case AV_PICTURE_TYPE_I: 330 flags |= 0x20; // doesnt_depend_on_other_samples 331 if(avctx->gop_size > 1) 332 flags |= 0x04; // other_samples_depend_on_this_one 333 if(avctx->max_b_frames > 0) 334 flags |= 0x40; // earlier_dps_allowed 335 break; 336 case AV_PICTURE_TYPE_P: 337 flags |= 0x10; // sample_depends_on_others 338 if(avctx->max_b_frames > 0) 339 flags |= 0x40|0x04; // earlier_dps_allowed|other_samples_depend_on_this_one 340 break; 341 case AV_PICTURE_TYPE_B: 342 flags |= 0x10|0x08; // sample_depends_on_others|no_other_samples_depend_on_this_one 343 break; 344 default:; 345 } 346 347 return (uint8_t)flags; 348 } 349 350 static void maybe_add_sdtp_entry(quicktime_t* file, long sample, int track) 351 { 352 quicktime_video_map_t *vtrack = &file->vtracks[track]; 353 quicktime_ffmpeg_video_codec_t *codec = vtrack->codec->priv; 354 355 if (codec->encoder->id == CODEC_ID_MPEG2VIDEO && codec->avctx->gop_size > 1) 356 { 357 uint8_t flags = generate_sdtp_flags_mpeg2(sample, codec->avctx); 358 quicktime_insert_sdtp_entry(file, sample, track, flags); 359 } 360 } 361 362 294 363 #ifndef HAVE_LIBSWSCALE 295 364 static void fill_avpicture(AVPicture * ret, unsigned char ** rows, 296 365 int lqt_colormodel, … … 400 469 codec->reinterpret_pix_fmt = codec->avctx->pix_fmt; 401 470 402 471 /* First we try codec-specific colormodel matching. */ 403 if(codec->decoder->id == CODEC_ID_DNXHD) 472 if(codec->is_imx && quicktime_match_32(vtrack->track->mdia.minf.stbl.stsd.table[0].format, "AVmp")) 473 { 474 if (lqt_ffmpeg_get_avid_yuv_range(vtrack->track) == AVID_FULL_YUV_RANGE) 475 { 476 vtrack->stream_cmodel = BC_YUVJ422P; 477 codec->reinterpret_pix_fmt = PIX_FMT_YUVJ422P; 478 *exact = 1; 479 return; 480 } 481 } 482 else if(codec->decoder->id == CODEC_ID_DNXHD) 404 483 { 405 484 /* FFMpeg supports PIX_FMT_YUV422P and PIX_FMT_YUV422P10 for DNxHD, which 406 485 we sometimes interpret as PIX_FMT_YUVJ422P and PIX_FMT_YUVJ422P10. */ … … 662 741 codec->y_offset = codec->avctx->height - trak->tkhd.track_height; 663 742 vtrack->height_extension = 0; 664 743 } else { 744 int stsd_height = trak->mdia.minf.stbl.stsd.table[0].height; 665 745 codec->y_offset = 0; 666 if (vtrack->height_extension == codec->avctx->height - trak->tkhd.track_height) {746 if (vtrack->height_extension == codec->avctx->height - stsd_height) { 667 747 return; 668 748 } 669 749 670 vtrack->height_extension = codec->avctx->height - trak->tkhd.track_height;750 vtrack->height_extension = codec->avctx->height - stsd_height; 671 751 672 752 /* Now we need a larger temp_frame */ 673 753 if (vtrack->temp_frame) { … … 883 963 &got_pic, 884 964 &codec->pkt) < 0) 885 965 { 886 lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "Skipping corrupted frame"); 887 continue; 966 lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "Broken frame encountered"); 967 codec->decoding_delay--; 968 return 1; 888 969 } 889 970 890 971 #if LIBAVCODEC_VERSION_MAJOR >= 54 … … 907 988 codec->buffer, 908 989 buffer_size) < 0) 909 990 { 910 lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "Skipping corrupted frame"); 911 continue; 991 lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "Broken frame encountered"); 992 codec->decoding_delay--; 993 return 1; 912 994 } 913 995 #endif 914 996 if(got_pic) 915 997 codec->decoding_delay--; 916 998 917 999 if((buffer_size <= 0) && !got_pic) 918 return 0;1000 return 1; 919 1001 } 920 1002 } 921 1003 … … 972 1054 973 1055 vtrack->chroma_placement = LQT_CHROMA_PLACEMENT_MPEG2; 974 1056 vtrack->ci.id = LQT_COMPRESSION_D10; 975 vtrack->ci.bitrate = 976 (trak->mdia.minf.stbl.stsd.table[0].format[2] - '0') * 977 10000000; 1057 if (quicktime_match_32(trak->mdia.minf.stbl.stsd.table[0].format, "AVmp")) 1058 vtrack->ci.bitrate = 50000000; 1059 else 1060 vtrack->ci.bitrate = 1061 (trak->mdia.minf.stbl.stsd.table[0].format[2] - '0') * 10000000; 978 1062 } 979 1063 980 1064 if(codec->avctx->sample_aspect_ratio.num) … … 1030 1114 return result; 1031 1115 } 1032 1116 1117 static int64_t bitstream_i_frame_to_display_frame(int64_t bitstream_i_frame, quicktime_bframe_detector* bframe_detector) 1118 { 1119 if (!bframe_detector) 1120 return bitstream_i_frame; // Assuming closed GOP. 1121 else 1122 { // This branch can also handle P-frames, though we aren't relying on that. 1123 int num_following_b_frames = 0; 1124 while (quicktime_is_bframe(bframe_detector, bitstream_i_frame + num_following_b_frames + 1) == 1) 1125 { 1126 num_following_b_frames++; 1127 } 1128 return bitstream_i_frame + num_following_b_frames; 1129 } 1130 } 1131 1132 static int64_t bitstream_b_frame_to_display_frame(int64_t bitstream_b_frame) 1133 { 1134 return bitstream_b_frame - 1; 1135 } 1136 1137 static int64_t get_bitstream_sync_frame(quicktime_t* file, int64_t display_frame, int track, quicktime_bframe_detector* bframe_detector) 1138 { 1139 int64_t full_sync_kf = quicktime_get_keyframe_before(file, display_frame, track); 1140 int64_t partial_sync_kf = quicktime_get_partial_keyframe_before(file, display_frame, track); 1141 1142 while (partial_sync_kf > full_sync_kf && partial_sync_kf > 0) 1143 { 1144 if (bitstream_i_frame_to_display_frame(partial_sync_kf, bframe_detector) <= display_frame) 1145 return partial_sync_kf; 1146 1147 partial_sync_kf = quicktime_get_partial_keyframe_before(file, partial_sync_kf - 1, track); 1148 } 1149 1150 return full_sync_kf; 1151 } 1152 1033 1153 static void resync_ffmpeg(quicktime_t *file, int track) 1034 1154 { 1035 int64_t keyframe, frame;1036 int buffer_size, got_pic;1037 1155 quicktime_video_map_t *vtrack = &file->vtracks[track]; 1038 1156 quicktime_ffmpeg_video_codec_t *codec = vtrack->codec->priv; 1039 1157 1158 const int64_t target_display_frame = vtrack->current_position; // Frame we are told to seek to. 1159 int64_t bitstream_frame; // Current working frame in bitstream order. 1160 int64_t buffer_size; 1161 const int64_t total_frames = quicktime_video_length(file, track); 1162 int decoded_frames_to_discard = 0; 1163 int seen_non_b_frames = 0; 1164 const int detect_bframes = vtrack->track->mdia.minf.stbl.has_ctts; 1165 quicktime_bframe_detector* bframe_detector = detect_bframes ? &codec->bframe_detector : NULL; 1166 1040 1167 /* Forget about previously decoded frame */ 1041 1168 codec->have_frame = 0; 1042 1169 codec->decoding_delay = 0; 1043 1170 1044 1171 /* Reset lavc */ 1045 1172 avcodec_flush_buffers(codec->avctx); 1046 1173 1047 1048 if(quicktime_has_keyframes(file, track)) 1174 if(target_display_frame <= 0) 1175 return; 1176 1177 if(!quicktime_has_keyframes(file, track)) 1178 return; // Assuming I-frame only stream. 1179 1180 bitstream_frame = get_bitstream_sync_frame(file, target_display_frame, track, bframe_detector); 1181 decoded_frames_to_discard = target_display_frame - bitstream_i_frame_to_display_frame(bitstream_frame, bframe_detector); 1182 1183 for (;; bitstream_frame++) 1049 1184 { 1050 keyframe = quicktime_get_keyframe_before(file, vtrack->current_position, track);1185 int got_pic = 0; 1051 1186 1052 frame = keyframe; 1053 1054 while(frame < vtrack->current_position) 1187 if (decoded_frames_to_discard <= 0) // Should not be < 0 unless the stream is broken. 1055 1188 { 1189 // We want vtrack->current_position + codec->decoding_delay == bitstream_frame 1190 // when the next encoded frame is read. 1191 codec->decoding_delay = bitstream_frame - vtrack->current_position; 1192 break; 1193 } 1194 1195 if (bitstream_frame < total_frames) 1196 { 1197 if (detect_bframes) 1198 { 1199 int is_bframe = quicktime_is_bframe(bframe_detector, bitstream_frame); 1200 if (!is_bframe) 1201 seen_non_b_frames++; 1202 1203 // Skip initial B-frames. 1204 if (is_bframe && seen_non_b_frames < 2) 1205 continue; 1206 1207 // Don't do IDCT where we don't have to. 1208 if (is_bframe && bitstream_b_frame_to_display_frame(bitstream_frame) < target_display_frame) 1209 codec->avctx->skip_idct = AVDISCARD_NONREF; 1210 } 1211 1056 1212 buffer_size = lqt_read_video_frame(file, &codec->buffer, 1057 1213 &codec->buffer_alloc, 1058 frame + codec->decoding_delay, 1059 NULL, track); 1060 if(buffer_size > 0) 1061 { 1214 bitstream_frame, NULL, track); 1215 } 1216 else // if (bitstream_frame < total_frames) 1217 { 1218 // Feed an empty packet to the decoder to indicate end of stream, 1219 // which will make it return the final decoded frames it still owes us. 1220 buffer_size = 0; 1221 } 1222 1062 1223 #if LIBAVCODEC_BUILD >= ((52<<16)+(26<<8)+0) 1063 codec->pkt.data = codec->buffer; 1064 codec->pkt.size = buffer_size; 1065 avcodec_decode_video2(codec->avctx, 1066 codec->frame, 1067 &got_pic, 1068 &codec->pkt); 1224 codec->pkt.data = codec->buffer; 1225 codec->pkt.size = buffer_size; 1226 avcodec_decode_video2(codec->avctx, codec->frame, &got_pic, &codec->pkt); 1069 1227 #else 1070 avcodec_decode_video(codec->avctx, 1071 codec->frame, 1072 &got_pic, 1073 codec->buffer, 1074 buffer_size); 1228 avcodec_decode_video(codec->avctx, codec->frame, &got_pic, codec->buffer, buffer_size); 1075 1229 #endif 1076 if(!got_pic) 1077 { 1078 codec->decoding_delay++; 1079 frame--; 1080 } 1081 } 1082 frame++; 1230 1231 // Default value is necessary for normal decoding. 1232 codec->avctx->skip_idct = AVDISCARD_DEFAULT; 1233 1234 if(got_pic) 1235 decoded_frames_to_discard--; 1236 else if (bitstream_frame >= total_frames) 1237 { 1238 // We've already fed an empty packet to the decoder, indicating 1239 // no more data will follow, yet it didn't return any additional 1240 // frames. At this point we give up and declare decoding failure. 1241 break; 1083 1242 } 1084 } 1243 } // for (;; bitstream_frame++) 1085 1244 } 1086 1245 1087 1246 static int set_pass_ffmpeg(quicktime_t *file, … … 1128 1287 1129 1288 } 1130 1289 1290 static const char* get_xdcam_hd422_fourcc(quicktime_t *file, int track, int height) 1291 { 1292 quicktime_video_map_t *vtrack = &file->vtracks[track]; 1293 int time_scale = lqt_video_time_scale(file, track); 1294 int frame_duration = lqt_frame_duration(file, track, NULL); 1295 int interlaced = vtrack->interlace_mode != LQT_INTERLACE_NONE; 1296 int frame_rate_100; // Frame rate with 2 decimal places preserved, multiplied by 100. 1297 1298 if(frame_duration <= 0 || time_scale <= 0) 1299 return NULL; // Sanity check. 1300 1301 frame_rate_100 = time_scale * 100 / frame_duration; 1302 1303 if(height == 720 && !interlaced) // Only progressive modes are supported for 720 lines. 1304 { 1305 if(interlaced) 1306 { 1307 lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "XDCAM HD422 supports 720p but not 720i"); 1308 return NULL; 1309 } 1310 else 1311 { 1312 switch(frame_rate_100) 1313 { 1314 case 2397: 1315 return "xd54"; 1316 case 2500: 1317 return "xd55"; 1318 case 6000: 1319 return "xd59"; 1320 case 5000: 1321 return "xd5a"; 1322 } 1323 } 1324 } 1325 else if(height == 1080) 1326 { 1327 if(interlaced) 1328 { 1329 switch(frame_rate_100) 1330 { 1331 case 2500: 1332 return "xd5c"; 1333 case 2997: 1334 return "xd5b"; 1335 } 1336 } 1337 else // if(interlaced) 1338 { 1339 switch(frame_rate_100) 1340 { 1341 case 2397: 1342 return "xd5d"; 1343 case 2500: 1344 return "xd5e"; 1345 case 2997: 1346 return "xd5f"; 1347 } 1348 } 1349 } 1350 else if(height == 540) 1351 { 1352 lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "XDCAM HD422 540p is not supported"); 1353 return NULL; 1354 } 1355 else 1356 { 1357 lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "Frame height of %d is not supported by XDCAM HD422", height); 1358 return NULL; 1359 } 1360 1361 lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "Frame rate %d.%02d is not supported by XDCAM HD422, at least not for %d%c", 1362 frame_rate_100 / 100, frame_rate_100 % 100, height, interlaced ? 'i' : 'p'); 1363 return NULL; 1364 } 1365 1131 1366 static int init_imx_encoder(quicktime_t *file, int track) 1132 1367 { 1133 1368 quicktime_video_map_t *vtrack = &file->vtracks[track]; … … 1138 1373 codec->avctx->gop_size = 0; 1139 1374 codec->avctx->intra_dc_precision = 2; 1140 1375 codec->avctx->qmin = 1; 1141 codec->avctx->qmax = 3;1376 codec->avctx->qmax = codec->imx_bitrate == 30 ? 8 : 3; 1142 1377 codec->avctx->rtp_payload_size = 1; // ?? 1143 1378 codec->avctx->rc_buffer_aggressivity = 0.25; 1144 1379 codec->avctx->flags |= CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_LOW_DELAY; … … 1185 1420 return 0; 1186 1421 } 1187 1422 1423 static int init_xdcam_hd422_encoder(quicktime_t *file, int track) 1424 { 1425 quicktime_video_map_t *vtrack = &file->vtracks[track]; 1426 quicktime_ffmpeg_video_codec_t *codec = vtrack->codec->priv; 1427 quicktime_trak_t *trak = vtrack->track; 1428 int height = trak->tkhd.track_height; 1429 int time_scale = lqt_video_time_scale(file, track); 1430 int frame_duration = lqt_frame_duration(file, track, NULL); 1431 const char* fourcc; 1432 1433 codec->avctx->pix_fmt = PIX_FMT_YUV422P; 1434 codec->avctx->gop_size = time_scale > 25 * frame_duration ? 15 : 12; 1435 codec->avctx->max_b_frames = 2; 1436 codec->avctx->intra_dc_precision = 2; 1437 codec->avctx->qmin = 1; 1438 codec->avctx->qmax = 12; // The maximum value compatible with non_linear_quant option. 1439 codec->avctx->lmin = FF_QP2LAMBDA; 1440 1441 // XDCAM is meant to use open GOPs. From time to time we might want to insert closed GOPs 1442 // like some other encoders do, but libavcodec only checks this flag once. 1443 codec->avctx->flags &= ~CODEC_FLAG_CLOSED_GOP; 1444 1445 if(vtrack->interlace_mode != LQT_INTERLACE_NONE) 1446 codec->avctx->flags |= CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME; 1447 1448 #if (LIBAVCODEC_VERSION_MAJOR < 54) 1449 codec->avctx->flags2 |= CODEC_FLAG2_INTRA_VLC|CODEC_FLAG2_NON_LINEAR_QUANT; 1450 #else 1451 av_dict_set(&codec->options, "non_linear_quant", "1", 0); 1452 av_dict_set(&codec->options, "intra_vlc", "1", 0); 1453 #endif 1454 1455 codec->avctx->bit_rate = 50*1000*1000; 1456 codec->avctx->rc_max_rate = codec->avctx->bit_rate; 1457 codec->avctx->rc_min_rate = codec->avctx->bit_rate; 1458 codec->avctx->rc_buffer_size = 17825792; 1459 codec->avctx->rc_initial_buffer_occupancy = codec->avctx->rc_buffer_size; 1460 codec->avctx->scenechange_threshold = 1000*1000*1000; 1461 1462 fourcc = get_xdcam_hd422_fourcc(file, track, height); 1463 if (fourcc) 1464 { 1465 memcpy(trak->mdia.minf.stbl.stsd.table[0].format, fourcc, 4); 1466 return 0; 1467 } 1468 1469 return -1; 1470 } 1471 1472 #ifdef HAVE_PRORES_SUPPORT 1473 static int init_prores_encoder(quicktime_t *file, int track) 1474 { 1475 quicktime_video_map_t *vtrack = &file->vtracks[track]; 1476 quicktime_trak_t *trak = vtrack->track; 1477 quicktime_ffmpeg_video_codec_t *codec = vtrack->codec->priv; 1478 int height = trak->tkhd.track_height; 1479 1480 if(vtrack->interlace_mode != LQT_INTERLACE_NONE) 1481 codec->avctx->flags |= CODEC_FLAG_INTERLACED_DCT; 1482 1483 // Color parameters go into ProRes bitstream. 1484 if (trak->mdia.minf.stbl.stsd.table->has_colr) 1485 { 1486 // If COLR atom was provided by the client, use that. 1487 const quicktime_colr_t* colr = &trak->mdia.minf.stbl.stsd.table->colr; 1488 codec->avctx->color_primaries = colr->primaries; 1489 codec->avctx->color_trc = colr->transferFunction; 1490 codec->avctx->colorspace = colr->matrix; 1491 } 1492 else 1493 { 1494 // Try to guess the correct parameters. 1495 if (height >= 720) 1496 { 1497 codec->avctx->color_primaries = AVCOL_PRI_BT709; 1498 codec->avctx->color_trc = AVCOL_TRC_BT709; 1499 codec->avctx->colorspace = AVCOL_SPC_BT709; 1500 } 1501 else if (height >= 576) 1502 { 1503 codec->avctx->color_primaries = AVCOL_PRI_BT470BG; 1504 codec->avctx->color_trc = AVCOL_TRC_BT709; 1505 codec->avctx->colorspace = AVCOL_SPC_SMPTE170M; 1506 } 1507 else 1508 { 1509 codec->avctx->color_primaries = AVCOL_PRI_SMPTE170M; 1510 codec->avctx->color_trc = AVCOL_TRC_BT709; 1511 codec->avctx->colorspace = AVCOL_SPC_SMPTE170M; 1512 } 1513 } 1514 1515 av_dict_set(&codec->options, "profile", lqt_prores_profiles[codec->prores_profile].ffmpeg_profile, 0); 1516 memcpy(trak->mdia.minf.stbl.stsd.table[0].format, lqt_prores_profiles[codec->prores_profile].fourcc, 4); 1517 1518 return 0; 1519 } 1520 #endif 1521 1188 1522 static void setup_header_mpeg4(quicktime_t *file, int track, 1189 1523 const uint8_t * header, int header_len, 1190 1524 int advanced) … … 1294 1628 #endif 1295 1629 int64_t pts; 1296 1630 int kf; 1631 uint8_t* encoded_data; 1297 1632 1298 1633 if(!row_pointers) 1299 1634 { … … 1323 1658 /* time_base is 1/framerate for constant framerate */ 1324 1659 1325 1660 codec->avctx->time_base.den = lqt_video_time_scale(file, track); 1326 codec->avctx->time_base.num = lqt_frame_duration(file, track, NULL); 1661 codec->avctx->time_base.num = 1; // If we want variable frame durations, we need 1 here. 1662 codec->encoding_pts_factor = 1; 1327 1663 1328 // codec->avctx->time_base.den = 1; 1329 // codec->avctx->time_base.num = lqt_video_time_scale(file, track); 1664 // Codecs for which time_base.num == 1 causes problems. 1665 switch(codec->encoder->id) 1666 { 1667 // Variable duration frames won't work for these. 1668 case CODEC_ID_MPEG2VIDEO: 1669 case CODEC_ID_DVVIDEO: 1670 case CODEC_ID_DNXHD: 1671 codec->encoding_pts_factor = lqt_frame_duration(file, track, NULL); 1672 codec->avctx->time_base.num = codec->encoding_pts_factor; 1673 // time_base may be reduced by a common factor by libavcodec, 1674 // so we can't just use that. 1675 break; 1676 default:; 1677 } 1330 1678 1331 1679 if(codec->avctx->flags & CODEC_FLAG_QSCALE) 1332 1680 codec->avctx->global_quality = codec->qscale; … … 1335 1683 codec->avctx->height = height; 1336 1684 1337 1685 lqt_ffmpeg_setup_encoding_colormodel(vtrack); 1338 1686 #if ENCODE_VIDEO2 1687 codec->frame->width = width; 1688 codec->frame->height = height; 1689 codec->frame->format = codec->avctx->pix_fmt; 1690 #endif 1691 1339 1692 lqt_get_pixel_aspect(file, track, &pixel_width, &pixel_height); 1340 1693 codec->avctx->sample_aspect_ratio.num = pixel_width; 1341 1694 codec->avctx->sample_aspect_ratio.den = pixel_height; … … 1415 1768 } 1416 1769 else if(codec->is_imx) 1417 1770 init_imx_encoder(file, track); 1771 else if(codec->is_xdcam_hd422) 1772 init_xdcam_hd422_encoder(file, track); 1773 #ifdef HAVE_PRORES_SUPPORT 1774 else if(codec->encoder->id == CODEC_ID_PRORES) 1775 init_prores_encoder(file, track); 1776 #endif 1418 1777 1419 1778 /* Initialize 2-pass */ 1420 1779 if(codec->total_passes) … … 1515 1874 codec->frame->linesize[2] = vtrack->stream_row_span_uv; 1516 1875 } 1517 1876 1518 codec->frame->pts = vtrack->timestamp ;1877 codec->frame->pts = vtrack->timestamp / codec->encoding_pts_factor; 1519 1878 if(codec->avctx->flags & CODEC_FLAG_QSCALE) 1520 1879 codec->frame->quality = codec->qscale; 1521 #if def DO_INTERLACE1880 #if 1 1522 1881 if(vtrack->interlace_mode != LQT_INTERLACE_NONE) 1523 1882 { 1524 1883 codec->frame->interlaced_frame = 1; … … 1540 1899 else 1541 1900 bytes_encoded = 0; 1542 1901 1543 pts = pkt.pts; 1902 encoded_data = pkt.data; // May be different from codec->buffer! 1903 pts = pkt.pts * codec->encoding_pts_factor; 1544 1904 kf = !!(pkt.flags & AV_PKT_FLAG_KEY); 1545 1905 1546 1906 #else // Old … … 1553 1913 if(bytes_encoded < 0) 1554 1914 return -1; 1555 1915 1556 pts = codec->avctx->coded_frame->pts; 1916 encoded_data = codec->buffer; 1917 pts = codec->avctx->coded_frame->pts * encoding_pts_factor; 1557 1918 kf = codec->avctx->coded_frame->key_frame; 1558 1919 1559 1920 #endif 1560 1921 1922 if(kf && codec->is_xdcam_hd422 && vtrack->cur_chunk) 1923 kf = LQT_PARTIAL_KEY_FRAME; // For XDCAM, only the first key frame is full key frame. 1924 1561 1925 if(!was_initialized && codec->encoder->id == CODEC_ID_DNXHD) 1562 1926 setup_avid_atoms(file, vtrack, codec->buffer, bytes_encoded); 1563 1927 … … 1575 1939 kf); 1576 1940 1577 1941 result = !quicktime_write_data(file, 1578 codec->buffer,1942 encoded_data, 1579 1943 bytes_encoded); 1580 1944 1945 #if ENCODE_VIDEO2 1946 av_free_packet(&pkt); 1947 #endif 1948 1949 // Must go before lqt_write_frame_header() which increments vtrack->cur_chunk. 1950 // cur_chunk is a frame number in storage order. 1951 maybe_add_sdtp_entry(file, vtrack->cur_chunk, track); 1952 1581 1953 lqt_write_frame_footer(file, track); 1582 1954 1583 1955 /* Write stats */ … … 1642 2014 else 1643 2015 return 0; 1644 2016 1645 pts = pkt.pts ;2017 pts = pkt.pts * codec->encoding_pts_factor; 1646 2018 1647 2019 kf = !!(pkt.flags & AV_PKT_FLAG_KEY); 1648 2020 … … 1655 2027 if(bytes_encoded <= 0) 1656 2028 return 0; 1657 2029 1658 pts = codec->avctx->coded_frame->pts ;2030 pts = codec->avctx->coded_frame->pts * codec->encoding_pts_factor; 1659 2031 kf = codec->avctx->coded_frame->key_frame; 1660 2032 1661 2033 #endif 2034 2035 if(kf && codec->is_xdcam_hd422 && vtrack->cur_chunk) 2036 kf = LQT_PARTIAL_KEY_FRAME; // For XDCAM, only the first key frame is full key frame. 1662 2037 1663 2038 if(bytes_encoded) 1664 2039 { … … 1669 2044 codec->buffer, 1670 2045 bytes_encoded); 1671 2046 2047 // Must go before lqt_write_frame_header() which increments vtrack->cur_chunk. 2048 // cur_chunk is a frame number in storage order. 2049 maybe_add_sdtp_entry(file, vtrack->cur_chunk, track); 2050 1672 2051 lqt_write_frame_footer(file, track); 1673 2052 1674 2053 if((codec->pass == 1) && codec->avctx->stats_out && codec->stats_file) … … 1685 2064 const char *key, 1686 2065 const void *value) 1687 2066 { 2067 int i; 1688 2068 quicktime_video_map_t *vtrack = &file->vtracks[track]; 1689 2069 quicktime_ffmpeg_video_codec_t *codec = vtrack->codec->priv; 1690 2070 if(!strcasecmp(key, "ff_qscale")) … … 1706 2086 } 1707 2087 return 0; 1708 2088 } 2089 else if(!strcasecmp(key, "prores_profile")) 2090 { 2091 for(i = 0; i < sizeof(lqt_prores_profiles)/sizeof(lqt_prores_profiles[0]); i++) 2092 { 2093 if(!strcasecmp((const char*)value, lqt_prores_profiles[i].lqt_name)) 2094 { 2095 codec->prores_profile = i; 2096 break; 2097 } 2098 } 2099 } 1709 2100 1710 2101 lqt_ffmpeg_set_parameter(codec->avctx, 1711 2102 #if LIBAVCODEC_VERSION_MAJOR >= 54 … … 1796 2187 return 0; 1797 2188 } 1798 2189 2190 static int init_compressed_xdcam_hd422(quicktime_t * file, int track) 2191 { 2192 quicktime_video_map_t * vtrack = &file->vtracks[track]; 2193 2194 const char* fourcc = get_xdcam_hd422_fourcc(file, track, vtrack->ci.height); 2195 if (fourcc) 2196 { 2197 memcpy(vtrack->track->mdia.minf.stbl.stsd.table[0].format, fourcc, 4); 2198 return 0; 2199 } 2200 else 2201 return -1; 2202 } 2203 2204 static int writes_compressed_xdcam_hd422(lqt_file_type_t type, 2205 const lqt_compression_info_t * ci) 2206 { 2207 /* AVI doesn't support XDCAM family of formats */ 2208 if(type & (LQT_FILE_AVI | LQT_FILE_AVI_ODML)) 2209 return 0; 2210 2211 return ci->bitrate == 50000000; 2212 } 2213 1799 2214 1800 2215 static void append_data_h264(lqt_packet_t * p, uint8_t * data, int len, 1801 2216 int header_len) … … 1888 2303 #if LIBAVCODEC_VERSION_INT < ((53<<16)|(8<<8)|0) 1889 2304 codec->avctx = avcodec_alloc_context(); 1890 2305 #else 1891 codec->avctx = avcodec_alloc_context3( NULL);2306 codec->avctx = avcodec_alloc_context3((!vtrack || vtrack->do_encode) ? encoder : decoder); 1892 2307 #endif 1893 2308 codec->encoder = encoder; 1894 2309 codec->decoder = decoder; 1895 2310 2311 // vtrack can be NULL if called from lqt_writes_compressed 2312 if(vtrack) 2313 quicktime_init_bframe_detector(&codec->bframe_detector, vtrack); 2314 1896 2315 codec_base->priv = codec; 1897 2316 codec_base->delete_codec = lqt_ffmpeg_delete_video; 1898 2317 codec_base->flush = flush; … … 1909 2328 codec_base->init_compressed = init_compressed_mpeg4; 1910 2329 codec_base->write_packet = write_packet_mpeg4; 1911 2330 } 1912 else if(encoder->id == CODEC_ID_MPEG2VIDEO)1913 {1914 codec_base->writes_compressed = writes_compressed_imx;1915 codec_base->init_compressed = init_compressed_imx;1916 }1917 2331 else if(encoder->id == CODEC_ID_DVVIDEO) 1918 2332 { 1919 2333 codec_base->init_compressed = init_compressed_dv; … … 1959 2373 quicktime_match_32(compressor, "mx5p") || 1960 2374 quicktime_match_32(compressor, "mx3n") || 1961 2375 quicktime_match_32(compressor, "mx4n") || 1962 quicktime_match_32(compressor, "mx5n")) 2376 quicktime_match_32(compressor, "mx5n") || 2377 quicktime_match_32(compressor, "AVmp")) 1963 2378 { 1964 2379 vtrack->stream_cmodel = BC_YUV422P; 1965 2380 codec->is_imx = 1; 2381 codec_base->writes_compressed = writes_compressed_imx; 2382 codec_base->init_compressed = init_compressed_imx; 2383 } 2384 else if(quicktime_match_32(compressor, "xd54") || 2385 quicktime_match_32(compressor, "xd55") || 2386 quicktime_match_32(compressor, "xd5a") || 2387 quicktime_match_32(compressor, "xd5b") || 2388 quicktime_match_32(compressor, "xd5c") || 2389 quicktime_match_32(compressor, "xd5d") || 2390 quicktime_match_32(compressor, "xd5e") || 2391 quicktime_match_32(compressor, "xd5f")) 2392 { 2393 vtrack->stream_cmodel = BC_YUV422P; 2394 codec->is_xdcam_hd422 = 1; 2395 codec_base->writes_compressed = writes_compressed_xdcam_hd422; 2396 codec_base->init_compressed = init_compressed_xdcam_hd422; 2397 } 2398 else if(quicktime_match_32(compressor, "apch") || 2399 quicktime_match_32(compressor, "apcn") || 2400 quicktime_match_32(compressor, "apcs") || 2401 quicktime_match_32(compressor, "apco")) 2402 { 2403 vtrack->stream_cmodel = BC_YUV422P10; 1966 2404 } 1967 2405 else 1968 2406 vtrack->stream_cmodel = BC_YUV420P; -
plugins/png/qtpng.c
25 25 #include "lqt_private.h" 26 26 #include <quicktime/colormodels.h> 27 27 #include <png.h> 28 #include <string.h> 28 29 #include <stdlib.h> 29 30 #include "qtpng.h" 30 31 -
plugins/schroedinger/extract_settings.c
39 39 fprintf(stderr, " %s\n", s->enum_list[j]); 40 40 j++; 41 41 } 42 fprintf(stderr, "Default: %s\n", s->enum_list[(int)(s->default_value)]); 42 43 break; 43 44 case SCHRO_ENCODER_SETTING_TYPE_DOUBLE: 44 45 fprintf(stderr, "Double\n"); -
src/Makefile.am
99 99 stsd.c \ 100 100 stsdtable.c \ 101 101 stss.c \ 102 stps.c \ 103 sdtp.c \ 102 104 stsz.c \ 103 105 stts.c \ 104 106 texttrack.c \ … … 123 125 lqt_color.c \ 124 126 lqt_codecinfo.c \ 125 127 lqt_divx.c \ 126 lqt_qtvr.c 128 lqt_qtvr.c \ 129 bframe_detector.c 127 130 128 131 INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -
src/edts.c
43 43 { 44 44 quicktime_atom_t leaf_atom; 45 45 46 do46 while (quicktime_position(file) + 8 < edts_atom->end) 47 47 { 48 48 quicktime_atom_read_header(file, &leaf_atom); 49 49 if(quicktime_atom_is(&leaf_atom, "elst")) 50 { quicktime_read_elst(file, &edts->elst); }50 quicktime_read_elst(file, &edts->elst); 51 51 else 52 52 quicktime_atom_skip(file, &leaf_atom); 53 }while(quicktime_position(file) < edts_atom->end); 53 } 54 55 quicktime_set_position(file, edts_atom->end); 54 56 } 55 57 56 58 void quicktime_edts_dump(quicktime_edts_t *edts) -
src/lqt_codecinfo.c
601 601 { 602 602 char * pos; 603 603 int ret; 604 char * filename; 604 char * filename = NULL; 605 size_t filename_len = 0, new_size = 0; 605 606 DIR * directory; 606 607 struct dirent * directory_entry; 607 608 struct stat status; … … 611 612 lqt_codec_info_t * video_codecs_end; 612 613 lqt_codec_info_t * audio_codecs_end; 613 614 614 filename = malloc(PATH_MAX * sizeof(char));615 616 615 /* Set the end pointers so we can quickly add codecs after */ 617 616 618 617 … … 662 661 663 662 /* Now, the file should be a valid plugin, construct the filename */ 664 663 664 new_size = strlen(plugin_dir) + strlen(directory_entry->d_name) + 2; 665 if (new_size > filename_len) 666 { 667 filename_len = new_size; 668 filename = realloc(filename, filename_len); 669 if (!filename) 670 exit(EXIT_FAILURE); 671 } 665 672 strcpy(filename, plugin_dir); 666 673 strcat(filename, "/"); 667 674 strcat(filename, directory_entry->d_name); -
src/lqt_codecs.c
540 540 } 541 541 542 542 void lqt_write_frame_header(quicktime_t * file, int track, 543 int pic_num1, 544 int64_t pic_pts, intkeyframe)543 int pic_num1, int64_t pic_pts, 544 enum LqtKeyFrame keyframe) 545 545 { 546 546 quicktime_video_map_t * vtrack = &file->vtracks[track]; 547 547 quicktime_trak_t * trak = vtrack->track; … … 590 590 trak->chunk_samples = 1; 591 591 quicktime_write_chunk_footer(file, trak); 592 592 593 if(vtrack->keyframe )593 if(vtrack->keyframe == LQT_FULL_KEY_FRAME) 594 594 quicktime_insert_keyframe(file, vtrack->cur_chunk, track); 595 else if(vtrack->keyframe == LQT_PARTIAL_KEY_FRAME) 596 quicktime_insert_partial_keyframe(file, vtrack->cur_chunk, track); 597 595 598 vtrack->cur_chunk++; 596 599 } 597 600 … … 749 752 if(file->vtracks[track].timecode_track) 750 753 lqt_flush_timecode(file, track, time, 0); 751 754 752 file->vtracks[track].current_position++; 755 vtrack->current_position++; 756 757 /* vtrack->current_position now points past the last frame 758 we were asked to encode. If that frame was the last one 759 but flushing the codec produces more output, there will be 760 read access to vtrack->timestamps[vtrack->current_position] 761 from lqt_write_frame_header(), therefore we need to make sure 762 it's a valid address pointing to initialized memory. */ 763 if(vtrack->current_position >= vtrack->timestamps_alloc) 764 { 765 vtrack->timestamps_alloc += 1024; 766 vtrack->timestamps = realloc(vtrack->timestamps, 767 vtrack->timestamps_alloc * 768 sizeof(*vtrack->timestamps)); 769 } 770 vtrack->timestamps[vtrack->current_position] = -1; 753 771 return 0; 754 772 } 755 773 -
src/lqt_qtvr.c
202 202 file->moov.udta.ctyp[3] = 'r'; 203 203 file->moov.udta.is_qtvr = 1; 204 204 205 file->moov.mvhd.time_scale = time_scale; 206 205 207 trak = quicktime_add_track(file); 206 208 quicktime_trak_init_qtvr(file, trak, QTVR_OBJ, width, height, duration, time_scale); 207 209 quicktime_obji_init(&file->qtvr_node[0].obji); … … 225 227 file->moov.udta.ctyp[3] = 'r'; 226 228 file->moov.udta.is_qtvr = 1; 227 229 230 file->moov.mvhd.time_scale = time_scale; 231 228 232 trak = quicktime_add_track(file); 229 233 quicktime_trak_init_qtvr(file, trak, QTVR_PAN, width, height, duration, time_scale); 230 234 quicktime_pdat_init(&file->qtvr_node[0].pdat); -
src/lqt_quicktime.c
1440 1440 return 0; 1441 1441 } 1442 1442 1443 long quicktime_get_partial_keyframe_before(quicktime_t *file, long frame, int track) 1444 { 1445 quicktime_trak_t *trak = file->vtracks[track].track; 1446 quicktime_stps_t *stps = &trak->mdia.minf.stbl.stps; 1447 int i; 1448 1449 // Offset 1 1450 frame++; 1451 1452 for(i = stps->total_entries - 1; i >= 0; i--) 1453 { 1454 if(stps->table[i].sample <= frame) return stps->table[i].sample - 1; 1455 } 1456 1457 return 0; 1458 } 1459 1443 1460 #if 0 1444 1461 static long quicktime_get_keyframe_after(quicktime_t *file, long frame, int track) 1445 1462 { … … 1486 1503 stss->total_entries++; 1487 1504 } 1488 1505 1506 void quicktime_insert_partial_keyframe(quicktime_t *file, long frame, int track) 1507 { 1508 quicktime_trak_t *trak = file->vtracks[track].track; 1509 quicktime_stps_t *stps = &trak->mdia.minf.stbl.stps; 1510 1511 if(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML)) 1512 { 1513 // AVI doesn't support partial keyframes. 1514 return; 1515 } 1516 1517 // Expand table 1518 if(stps->entries_allocated <= stps->total_entries) 1519 { 1520 stps->entries_allocated += 1024; 1521 stps->table = realloc(stps->table, 1522 sizeof(*stps->table) * 1523 stps->entries_allocated); 1524 } 1525 1526 stps->table[stps->total_entries].sample = frame+1; 1527 stps->total_entries++; 1528 } 1529 1530 void quicktime_insert_sdtp_entry(quicktime_t *file, long sample, int track, uint8_t flags) 1531 { 1532 quicktime_trak_t *trak = file->vtracks[track].track; 1533 quicktime_sdtp_t *sdtp = &trak->mdia.minf.stbl.sdtp; 1534 1535 if(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML)) 1536 { 1537 // AVI doesn't support sdtp atom 1538 return; 1539 } 1540 1541 // Expand table 1542 if(sdtp->entries_allocated <= sample) 1543 { 1544 sdtp->entries_allocated = sdtp->entries_allocated * 2 + 512; 1545 sdtp->table = realloc(sdtp->table, sdtp->entries_allocated); 1546 memset(sdtp->table + sdtp->total_entries, 0, sdtp->entries_allocated - sdtp->total_entries); 1547 } 1548 1549 sdtp->table[sample] = flags; 1550 if(sdtp->total_entries <= sample) 1551 sdtp->total_entries = sample + 1; 1552 } 1489 1553 1490 1554 int quicktime_has_keyframes(quicktime_t *file, int track) 1491 1555 { … … 1521 1585 vtrack->current_position = 0; 1522 1586 vtrack->cur_chunk = 0; 1523 1587 vtrack->io_cmodel = BC_RGB888; 1588 vtrack->do_encode = encode; 1524 1589 quicktime_init_vcodec(vtrack, encode, info); 1525 1590 return 0; 1526 1591 } … … 1625 1690 quicktime_init_video_map(&file->vtracks[i], 1626 1691 file->wr, 1627 1692 (lqt_codec_info_t*)0); 1693 #if 0 1628 1694 /* Get decoder colormodel */ 1629 1695 file->vtracks[i].codec->decode_video(file, (uint8_t**)0, i); 1630 1696 file->vtracks[i].io_cmodel = file->vtracks[i].stream_cmodel; … … 1633 1699 quicktime_video_width(file, i), 1634 1700 &file->vtracks[i].stream_row_span, 1635 1701 &file->vtracks[i].stream_row_span_uv); 1636 1702 #endif 1637 1703 /* Get interlace mode */ 1638 1704 if((file->vtracks[i].interlace_mode == LQT_INTERLACE_NONE) && 1639 1705 (file->vtracks[i].track->mdia.minf.stbl.stsd.table[0].has_fiel)) … … 2054 2120 free(new_file); 2055 2121 new_file = 0; 2056 2122 } 2057 2058 2059 2123 2060 2124 if(rd && new_file) 2061 2125 { 2062 2126 /* Set default decoding parameters */ … … 2064 2128 lqt_set_default_audio_parameters(new_file, i); 2065 2129 2066 2130 for(i = 0; i < new_file->total_vtracks; i++) 2131 { 2067 2132 lqt_set_default_video_parameters(new_file, i); 2133 2134 /* 2135 * Get decoder colormodel 2136 * This might causing a first frame to be decoded, so we can't call this 2137 * before setting the parameters 2138 */ 2139 new_file->vtracks[i].codec->decode_video(new_file, (uint8_t**)0, i); 2140 new_file->vtracks[i].io_cmodel = new_file->vtracks[i].stream_cmodel; 2141 lqt_get_default_rowspan(new_file->vtracks[i].stream_cmodel, 2142 quicktime_video_width(new_file, i), 2143 &new_file->vtracks[i].stream_row_span, 2144 &new_file->vtracks[i].stream_row_span_uv); 2145 } 2068 2146 } 2069 2147 2070 2148 return new_file; -
src/stbl.c
31 31 quicktime_stsd_init(&stbl->stsd); 32 32 quicktime_stts_init(&stbl->stts); 33 33 quicktime_stss_init(&stbl->stss); 34 quicktime_stps_init(&stbl->stps); 34 35 quicktime_stsc_init(&stbl->stsc); 35 36 quicktime_stsz_init(&stbl->stsz); 37 quicktime_sdtp_init(&stbl->sdtp); 36 38 quicktime_stco_init(&stbl->stco); 37 39 } 38 40 … … 135 137 quicktime_stsd_delete(&stbl->stsd); 136 138 quicktime_stts_delete(&stbl->stts); 137 139 quicktime_stss_delete(&stbl->stss); 140 quicktime_stps_delete(&stbl->stps); 138 141 quicktime_stsc_delete(&stbl->stsc); 139 142 quicktime_stsz_delete(&stbl->stsz); 143 quicktime_sdtp_delete(&stbl->sdtp); 140 144 quicktime_stco_delete(&stbl->stco); 141 145 } 142 146 … … 147 151 quicktime_stts_dump(&stbl->stts); 148 152 if(stbl->stss.total_entries) 149 153 quicktime_stss_dump(&stbl->stss); 154 if(stbl->stps.total_entries) 155 quicktime_stps_dump(&stbl->stps); 150 156 quicktime_stsc_dump(&stbl->stsc); 151 157 quicktime_stsz_dump(&stbl->stsz); 158 if(stbl->sdtp.total_entries) 159 quicktime_sdtp_dump(&stbl->sdtp); 152 160 quicktime_stco_dump(&stbl->stco); 153 161 if(stbl->has_ctts) 154 162 quicktime_ctts_dump(&stbl->ctts); … … 187 195 quicktime_read_stss(file, &stbl->stss); 188 196 quicktime_atom_skip(file, &leaf_atom); 189 197 } 198 else if(quicktime_atom_is(&leaf_atom, "stps")) 199 { 200 quicktime_read_stps(file, &stbl->stps); 201 quicktime_atom_skip(file, &leaf_atom); 202 } 190 203 else if(quicktime_atom_is(&leaf_atom, "stsc")) 191 204 { 192 205 quicktime_read_stsc(file, &stbl->stsc); … … 197 210 quicktime_read_stsz(file, &stbl->stsz); 198 211 quicktime_atom_skip(file, &leaf_atom); 199 212 } 213 else if(quicktime_atom_is(&leaf_atom, "sdtp")) 214 { 215 // This atom doesn't have its own number_of_entries field. 216 long num_entries = stbl->stsz.total_entries; // That's what Apple docs tell us to use. 217 if(num_entries <= 0) 218 num_entries = leaf_atom.size - 12; // Fallback, in case stsz wasn't loaded yet. 219 quicktime_read_sdtp(file, &stbl->sdtp, num_entries); 220 quicktime_atom_skip(file, &leaf_atom); 221 } 200 222 else if(quicktime_atom_is(&leaf_atom, "co64")) 201 223 { 202 224 quicktime_read_stco64(file, &stbl->stco); … … 222 244 quicktime_write_stsd(file, minf, &stbl->stsd); 223 245 quicktime_write_stts(file, &stbl->stts); 224 246 quicktime_write_stss(file, &stbl->stss); 247 if(stbl->stps.total_entries) 248 quicktime_write_stps(file, &stbl->stps); 225 249 quicktime_write_stsc(file, &stbl->stsc); 226 250 quicktime_write_stsz(file, &stbl->stsz); 251 252 // Must go after stsz, as it doesn't have its own number_of_entries field 253 // and Apple docs say to use stsz.number_of_entries. 254 if(stbl->sdtp.total_entries) 255 quicktime_write_sdtp(file, &stbl->sdtp); 256 227 257 quicktime_write_stco(file, &stbl->stco); 228 258 if(stbl->has_ctts) 229 259 quicktime_write_ctts(file, &stbl->ctts); -
src/stsdtable.c
707 707 708 708 table->version = 0; 709 709 table->revision = 0; 710 table->vendor[0] = 'l'; 711 table->vendor[1] = 'q'; 712 table->vendor[2] = 't'; 713 table->vendor[3] = ' '; 710 711 /* We used to write "lqt " here, but some broken 712 software expects "appl" */ 713 table->vendor[0] = 'a'; 714 table->vendor[1] = 'p'; 715 table->vendor[2] = 'p'; 716 table->vendor[3] = 'l'; 714 717 715 718 table->temporal_quality = 100; 716 719 table->spatial_quality = 258; -
src/trak.c
427 427 int64_t result = 0; 428 428 429 429 if(trak->mdia.minf.stbl.stco.total_entries && 430 chunk > trak->mdia.minf.stbl.stco.total_entries)430 chunk >= trak->mdia.minf.stbl.stco.total_entries) 431 431 result = table[trak->mdia.minf.stbl.stco.total_entries - 1].offset; 432 432 else 433 433 if(trak->mdia.minf.stbl.stco.total_entries) -
new file src/bframe_detector.c
- + 1 /******************************************************************************* 2 trak.c 3 4 libquicktime - A library for reading and writing quicktime/avi/mp4 files. 5 http://libquicktime.sourceforge.net 6 7 Copyright (C) 2002 Heroine Virtual Ltd. 8 Copyright (C) 2002-2011 Members of the libquicktime project. 9 10 This library is free software; you can redistribute it and/or modify it under 11 the terms of the GNU Lesser General Public License as published by the Free 12 Software Foundation; either version 2.1 of the License, or (at your option) 13 any later version. 14 15 This library is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 18 details. 19 20 You should have received a copy of the GNU Lesser General Public License along 21 with this library; if not, write to the Free Software Foundation, Inc., 51 22 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 *******************************************************************************/ 24 25 #include "lqt_private.h" 26 27 void quicktime_init_bframe_detector(quicktime_bframe_detector* ctx, quicktime_video_map_t* vtrack) 28 { 29 ctx->frame = 0; 30 ctx->ctts_entry_idx = 0; 31 ctx->sample_within_entry = 0; 32 ctx->ctts = &vtrack->track->mdia.minf.stbl.ctts; 33 } 34 35 /* Returns 1 for true, 0 for false, or a negative value if impossible to tell. */ 36 int quicktime_is_bframe(quicktime_bframe_detector* ctx, int64_t frame) 37 { 38 39 if(ctx->ctts_entry_idx < 0 || ctx->ctts_entry_idx >= ctx->ctts->total_entries) 40 return -1; 41 42 if(frame > ctx->frame) 43 { 44 while(frame - ctx->frame >= ctx->ctts->table[ctx->ctts_entry_idx].sample_count - ctx->sample_within_entry) 45 { 46 if(ctx->ctts_entry_idx + 1 >= ctx->ctts->total_entries) 47 return -1; 48 49 ctx->frame += ctx->ctts->table[ctx->ctts_entry_idx].sample_count - ctx->sample_within_entry; 50 ctx->ctts_entry_idx++; 51 ctx->sample_within_entry = 0; 52 } 53 ctx->sample_within_entry += frame - ctx->frame; 54 ctx->frame = frame; 55 } 56 else if(frame < ctx->frame) 57 { 58 while(ctx->frame - frame > ctx->sample_within_entry) 59 { 60 if(ctx->ctts_entry_idx < 1) 61 return -1; 62 63 ctx->frame -= ctx->sample_within_entry + 1; 64 ctx->ctts_entry_idx--; 65 ctx->sample_within_entry = ctx->ctts->table[ctx->ctts_entry_idx].sample_count - 1; 66 } 67 ctx->sample_within_entry -= ctx->frame - frame; 68 ctx->frame = frame; 69 } 70 71 return ctx->ctts->table[ctx->ctts_entry_idx].sample_duration < 72 ctx->ctts->table[0].sample_duration;; 73 } -
new file src/sdtp.c
- + 1 /******************************************************************************* 2 sdtp.c 3 4 libquicktime - A library for reading and writing quicktime/avi/mp4 files. 5 http://libquicktime.sourceforge.net 6 7 Copyright (C) 2002-2011 Members of the libquicktime project. 8 9 This library is free software; you can redistribute it and/or modify it under 10 the terms of the GNU Lesser General Public License as published by the Free 11 Software Foundation; either version 2.1 of the License, or (at your option) 12 any later version. 13 14 This library is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 17 details. 18 19 You should have received a copy of the GNU Lesser General Public License along 20 with this library; if not, write to the Free Software Foundation, Inc., 51 21 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 *******************************************************************************/ 23 24 #include "lqt_private.h" 25 #include <stdlib.h> 26 #include <string.h> 27 28 void quicktime_sdtp_init(quicktime_sdtp_t *sdtp) 29 { 30 sdtp->version = 0; 31 sdtp->flags = 0; 32 sdtp->total_entries = 0; 33 sdtp->entries_allocated = 0; 34 sdtp->table = NULL; 35 } 36 37 void quicktime_sdtp_delete(quicktime_sdtp_t *sdtp) 38 { 39 if(sdtp->table) free(sdtp->table); 40 sdtp->total_entries = 0; 41 sdtp->entries_allocated = 0; 42 sdtp->table = 0; 43 } 44 45 void quicktime_sdtp_dump(quicktime_sdtp_t *sdtp) 46 { 47 long i; 48 lqt_dump(" sample dependencies (sdtp)\n"); 49 lqt_dump(" version %d\n", sdtp->version); 50 lqt_dump(" flags %ld\n", sdtp->flags); 51 lqt_dump(" total_entries %ld\n", sdtp->total_entries); 52 for(i = 0; i < sdtp->total_entries; i++) 53 { 54 unsigned flags = sdtp->table[i]; 55 char separator = ':'; 56 lqt_dump(" sample %ld: flags 0x%02x", i, flags); 57 if(flags & 1) 58 { 59 lqt_dump("%c has_redundant_coding", separator); 60 separator = ','; 61 } 62 if(flags & 2) 63 { 64 lqt_dump("%c no_redundant_coding", separator); 65 separator = ','; 66 } 67 if(flags & 4) 68 { 69 lqt_dump("%c other_samples_depend_on_this_one", separator); 70 separator = ','; 71 } 72 if(flags & 8) 73 { 74 lqt_dump("%c no_other_samples_depend_on_this_one", separator); 75 separator = ','; 76 } 77 if(flags & 16) 78 { 79 lqt_dump("%c sample_depends_on_others", separator); 80 separator = ','; 81 } 82 if(flags & 32) 83 { 84 lqt_dump("%c sample_doesnt_depend_on_others", separator); 85 separator = ','; 86 } 87 if(flags & 64) 88 { 89 lqt_dump("%c earlier_display_times_allowed", separator); 90 separator = ','; 91 } 92 if(flags & 128) 93 { 94 lqt_dump("%c reserved_bit_7", separator); 95 separator = ','; 96 } 97 lqt_dump("\n"); 98 } 99 } 100 101 void quicktime_read_sdtp(quicktime_t *file, quicktime_sdtp_t *sdtp, long num_entries) 102 { 103 sdtp->version = quicktime_read_char(file); 104 sdtp->flags = quicktime_read_int24(file); 105 sdtp->total_entries = num_entries; 106 107 if(sdtp->entries_allocated < sdtp->total_entries) 108 { 109 sdtp->entries_allocated = sdtp->total_entries; 110 sdtp->table = (uint8_t*)realloc(sdtp->table, sdtp->entries_allocated); 111 } 112 113 memset(sdtp->table, 0, sdtp->total_entries); 114 quicktime_read_data(file, sdtp->table, sdtp->total_entries); 115 } 116 117 void quicktime_write_sdtp(quicktime_t *file, quicktime_sdtp_t *sdtp) 118 { 119 quicktime_atom_t atom; 120 121 if(sdtp->total_entries) 122 { 123 quicktime_atom_write_header(file, &atom, "sdtp"); 124 125 quicktime_write_char(file, sdtp->version); 126 quicktime_write_int24(file, sdtp->flags); 127 quicktime_write_data(file, sdtp->table, sdtp->total_entries); 128 quicktime_atom_write_footer(file, &atom); 129 } 130 } -
new file src/stps.c
- + 1 /******************************************************************************* 2 stps.c 3 4 libquicktime - A library for reading and writing quicktime/avi/mp4 files. 5 http://libquicktime.sourceforge.net 6 7 Copyright (C) 2002 Heroine Virtual Ltd. 8 Copyright (C) 2002-2011 Members of the libquicktime project. 9 10 This library is free software; you can redistribute it and/or modify it under 11 the terms of the GNU Lesser General Public License as published by the Free 12 Software Foundation; either version 2.1 of the License, or (at your option) 13 any later version. 14 15 This library is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 18 details. 19 20 You should have received a copy of the GNU Lesser General Public License along 21 with this library; if not, write to the Free Software Foundation, Inc., 51 22 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 *******************************************************************************/ 24 25 #include "lqt_private.h" 26 #include <stdlib.h> 27 28 void quicktime_stps_init(quicktime_stps_t *stps) 29 { 30 stps->version = 0; 31 stps->flags = 0; 32 stps->total_entries = 0; 33 stps->entries_allocated = 0; 34 stps->table = NULL; 35 } 36 37 void quicktime_stps_delete(quicktime_stps_t *stps) 38 { 39 if(stps->table) free(stps->table); 40 stps->total_entries = 0; 41 stps->entries_allocated = 0; 42 stps->table = 0; 43 } 44 45 void quicktime_stps_dump(quicktime_stps_t *stps) 46 { 47 int i; 48 lqt_dump(" partial sync sample (stps)\n"); 49 lqt_dump(" version %d\n", stps->version); 50 lqt_dump(" flags %ld\n", stps->flags); 51 lqt_dump(" total_entries %ld\n", stps->total_entries); 52 for(i = 0; i < stps->total_entries; i++) 53 { 54 lqt_dump(" sample %lx\n", stps->table[i].sample); 55 } 56 } 57 58 void quicktime_read_stps(quicktime_t *file, quicktime_stps_t *stps) 59 { 60 int i; 61 stps->version = quicktime_read_char(file); 62 stps->flags = quicktime_read_int24(file); 63 stps->total_entries = quicktime_read_int32(file); 64 65 if(stps->entries_allocated < stps->total_entries) 66 { 67 stps->entries_allocated = stps->total_entries; 68 stps->table = (quicktime_stps_table_t*)realloc(stps->table, sizeof(quicktime_stps_table_t) * stps->entries_allocated); 69 } 70 71 for(i = 0; i < stps->total_entries; i++) 72 { 73 stps->table[i].sample = quicktime_read_int32(file); 74 } 75 } 76 77 78 void quicktime_write_stps(quicktime_t *file, quicktime_stps_t *stps) 79 { 80 int i; 81 quicktime_atom_t atom; 82 83 if(stps->total_entries) 84 { 85 quicktime_atom_write_header(file, &atom, "stps"); 86 87 quicktime_write_char(file, stps->version); 88 quicktime_write_int24(file, stps->flags); 89 quicktime_write_int32(file, stps->total_entries); 90 for(i = 0; i < stps->total_entries; i++) 91 { 92 quicktime_write_int32(file, stps->table[i].sample); 93 } 94 95 quicktime_atom_write_footer(file, &atom); 96 } 97 }