1 /* General codec for all MPEG-4 derived encoding. */
2 /* Uses ffmpeg and encore50. */
3 /* Encore50 still seemed to provide better results than ffmpeg for encoding */
4 /* so it does all the generic MPEG-4 encoding. */
11 #include "colormodels.h"
12 #include "funcprotos.h"
14 #include "quicktime.h"
15 #include "workarounds.h"
16 #include ENCORE_INCLUDE
17 //#include DECORE_INCLUDE
26 #define FRAME_RATE_BASE 10000
34 quicktime_ffmpeg_t
*decoder
;
45 int encode_initialized
[FIELDS
];
46 // Information for picking the right library routines.
47 // ID out of avcodec.h for the codec used.
48 // Invalid if encore50 is used.
50 // True if encore50 is being used.
54 AVCodec
*encoder
[FIELDS
];
55 AVCodecContext
*encoder_context
[FIELDS
];
56 AVFrame picture
[FIELDS
];
60 int encode_handle
[FIELDS
];
61 ENC_PARAM enc_param
[FIELDS
];
62 // Must count pframes in VBR
66 // Encoding parameters
68 // For heroine 60 encoding, we want different streams for each field.
70 long rc_period
; // the intended rate control averaging period
71 long rc_reaction_period
; // the reation period for rate control
72 long rc_reaction_ratio
; // the ratio for down/up rate control
73 long max_key_interval
; // the maximum interval between key frames
74 int bitrate_tolerance
;
77 int max_quantizer
; // the upper limit of the quantizer
78 int min_quantizer
; // the lower limit of the quantizer
79 int quantizer
; // For vbr
80 int quality
; // the forward search range for motion estimation
85 // Temporary storage for color conversions
87 // Storage of compressed data
88 unsigned char *work_buffer
;
89 // Allocation of work_buffer
91 } quicktime_mpeg4_codec_t
;
95 // Decore needs the user to specify handles
96 static int decode_handle
= 1;
97 static int encode_handle
= 0;
107 // Direct copy routines
110 // Determine of the compressed frame is a keyframe for direct copy
111 int quicktime_mpeg4_is_key(unsigned char *data
, long size
, char *codec_id
)
116 if(quicktime_match_32(codec_id
, QUICKTIME_DIVX
) ||
117 quicktime_match_32(codec_id
, QUICKTIME_MP4V
) ||
118 quicktime_match_32(codec_id
, QUICKTIME_HV60
))
120 for(i
= 0; i
< size
- 5; i
++)
122 if( data
[i
] == 0x00 &&
123 data
[i
+ 1] == 0x00 &&
124 data
[i
+ 2] == 0x01 &&
127 if((data
[i
+ 4] & 0xc0) == 0x0)
138 // Test for VOL header in frame
139 int quicktime_mpeg4_has_vol(unsigned char *data
)
141 if( data
[0] == 0x00 &&
157 static void putbits(unsigned char **data
,
164 value
&= 0xffffffffffffffffLL
>> (64 - count
);
166 while(64 - *bit_pos
< count
)
168 *(*data
)++ = (*bit_store
) >> 56;
173 (*bit_store
) |= value
<< (64 - count
- *bit_pos
);
179 static void flushbits(unsigned char **data
,
183 //printf("flushbits %llx\n", (*bit_store));
184 while((*bit_pos
) > 0)
186 *(*data
)++ = (*bit_store
) >> 56;
195 #define VO_START_CODE 0x8
196 #define VO_START_CODE_LENGTH 27
197 #define VOL_START_CODE 0x12 /* 25-MAR-97 JDL : according to WD2 */
198 #define VOL_START_CODE_LENGTH 28
202 int quicktime_mpeg4_write_vol(unsigned char *data_start
,
205 int time_increment_resolution
,
209 int bits
, fixed_vop_time_increment
;
210 unsigned char *data
= data_start
;
217 vol_width
= quicktime_quantize16(vol_width
);
218 vol_height
= quicktime_quantize16(vol_height
);
225 VO_START_CODE_LENGTH
, VO_START_CODE
);
230 5, 0); /* vo_id = 0 */
236 VOL_START_CODE_LENGTH
, VOL_START_CODE
);
244 4, 0); /* vol_id = 0 */
250 1, 0); /* random_accessible_vol = 0 */
255 8, 1); /* video_object_type_indication = 1 video */
260 1, 1); /* is_object_layer_identifier = 1 */
265 4, 2); /* visual_object_layer_ver_id = 2 */
270 3, 1); /* visual_object_layer_priority = 1 */
275 4, 1); /* aspect_ratio_info = 1 */
287 1, 0); /* vol_control_parameter = 0 */
292 2, 0); /* vol_shape = 0 rectangular */
309 16, time_increment_resolution
);
319 1, 1); /* fixed_vop_rate = 1 */
323 while((1 << bits
) < time_increment_resolution
) bits
++;
325 // Log calculation fails for some reason
326 // bits = (int)ceil(log((double)time_increment_resolution) / log(2.0));
327 // if (bits < 1) bits=1;
329 fixed_vop_time_increment
=
330 (int)(time_increment_resolution
/ frame_rate
+ 0.1);
336 bits
, fixed_vop_time_increment
);
369 1, 0); /* interlaced = 0 */
374 1, 1); /* OBMC_disabled = 1 */
379 2, 0); /* vol_sprite_usage = 0 */
384 1, 0); /* not_8_bit = 0 */
390 1, 0); /* vol_quant_type = 0 */
395 1, 0); /* vol_quarter_pixel = 0 */
400 1, 1); /* complexity_estimation_disabled = 1 */
405 1, 1); /* resync_marker_disabled = 1 */
410 1, 0); /* data_partitioning_enabled = 0 */
415 1, 0); /* scalability = 0 */
423 * for(i = 0; i < data - data_start; i++)
424 * for(j = 0x80; j >= 1; j /= 2)
425 * printf("%d", (data_start[i] & j) ? 1 : 0);
431 return data
- data_start
;
436 // Create the header for the esds block which is used in mp4v.
437 // Taken from libavcodec
439 static int write_mp4v_header(unsigned char *data
,
444 unsigned char *start
= data
;
448 * static unsigned char test[] =
451 * 0x00, 0x00, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x01, 0xb5, 0x89, 0x13,
452 * 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xc4, 0x8d,
453 * 0x8a, 0xee, 0x05, 0x28, 0x04, 0x5a, 0x14, 0x63, 0x00, 0x00, 0x01, 0xb2,
454 * 0x46, 0x46, 0x6d, 0x70, 0x65, 0x67, 0x43, 0x56, 0x53, 0x62, 0x34, 0x37,
458 * memcpy(data, test, sizeof(test));
460 * return sizeof(test);
464 // Advanced simple level 1
465 // int profile_level = 0xf3;
467 int profile_level
= 0x1;
468 // int vo_version_id = 5;
469 int vo_version_id
= 1;
480 *data
++ = profile_level
;
482 // Visual object startcode
487 *data
++ = ((unsigned char)0x1 << 7) |
488 ((unsigned char)vo_version_id
<< 3) |
491 // visual object type video
492 *data
++ = (0x1 << 4) |
503 int vol_size
= quicktime_mpeg4_write_vol(data
,
521 static int reads_colormodel(quicktime_t
*file
,
525 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
526 quicktime_codec_t
*codec
= (quicktime_codec_t
*)vtrack
->codec
;
527 return (colormodel
== BC_YUV420P
&&
528 !quicktime_match_32(QUICKTIME_SVQ1
, codec
->fourcc
));
531 static int writes_colormodel(quicktime_t
*file
,
535 return colormodel
== BC_YUV420P
;
540 static int decode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
542 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
543 quicktime_trak_t
*trak
= vtrack
->track
;
544 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
545 quicktime_stsd_table_t
*stsd_table
= &trak
->mdia
.minf
.stbl
.stsd
.table
[0];
546 int width
= trak
->tkhd
.track_width
;
547 int height
= trak
->tkhd
.track_height
;
551 if(!codec
->decoder
) codec
->decoder
= quicktime_new_ffmpeg(
559 if(codec
->decoder
) result
= quicktime_ffmpeg_decode(
570 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
572 int64_t offset
= quicktime_position(file
);
573 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
574 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
575 quicktime_trak_t
*trak
= vtrack
->track
;
576 int width
= trak
->tkhd
.track_width
;
577 int height
= trak
->tkhd
.track_height
;
578 int width_i
= quicktime_quantize16(width
);
579 int height_i
= quicktime_quantize16(height
);
584 int current_field
= vtrack
->current_position
% codec
->total_fields
;
585 quicktime_atom_t chunk_atom
;
591 pthread_mutex_lock(&ffmpeg_lock
);
595 if(!codec
->encode_initialized
[current_field
])
598 if(codec
->ffmpeg_id
== CODEC_ID_MPEG4
&& codec
->use_encore
)
600 codec
->encode_initialized
[current_field
] = 1;
601 codec
->encode_handle
[current_field
] = encode_handle
++;
602 codec
->enc_param
[current_field
].x_dim
= width_i
;
603 codec
->enc_param
[current_field
].y_dim
= height_i
;
604 codec
->enc_param
[current_field
].framerate
=
605 quicktime_frame_rate(file
, track
) / codec
->total_fields
;
606 codec
->enc_param
[current_field
].bitrate
=
607 codec
->bitrate
/ codec
->total_fields
;
608 codec
->enc_param
[current_field
].rc_period
= codec
->rc_period
;
609 codec
->enc_param
[current_field
].rc_reaction_period
= codec
->rc_reaction_period
;
610 codec
->enc_param
[current_field
].rc_reaction_ratio
= codec
->rc_reaction_ratio
;
611 codec
->enc_param
[current_field
].max_quantizer
= codec
->max_quantizer
;
612 codec
->enc_param
[current_field
].min_quantizer
= codec
->min_quantizer
;
613 codec
->enc_param
[current_field
].max_key_interval
= codec
->max_key_interval
;
615 codec
->enc_param
[current_field
].search_range
= codec
->quality
* 3;
616 if(codec
->enc_param
[current_field
].search_range
> 15)
617 codec
->enc_param
[current_field
].search_range
= 15;
619 encore(codec
->encode_handle
[current_field
],
621 &codec
->enc_param
[current_field
], NULL
);
627 static char *video_rc_eq
="tex^qComp";
628 codec
->encode_initialized
[current_field
] = 1;
629 if(!ffmpeg_initialized
)
631 ffmpeg_initialized
= 1;
633 avcodec_register_all();
636 codec
->encoder
[current_field
] = avcodec_find_encoder(codec
->ffmpeg_id
);
637 if(!codec
->encoder
[current_field
])
639 printf("encode: avcodec_find_encoder returned NULL.\n");
640 pthread_mutex_unlock(&ffmpeg_lock
);
644 codec
->encoder_context
[current_field
] = avcodec_alloc_context();
645 AVCodecContext
*context
= codec
->encoder_context
[current_field
];
647 context
->width
= width_i
;
648 context
->height
= height_i
;
649 context
->gop_size
= codec
->gop_size
;
650 context
->pix_fmt
= PIX_FMT_YUV420P
;
651 context
->bit_rate
= codec
->bitrate
/ codec
->total_fields
;
652 context
->bit_rate_tolerance
= codec
->bitrate_tolerance
;
653 context
->rc_eq
= video_rc_eq
;
654 context
->rc_max_rate
= 0;
655 context
->rc_min_rate
= 0;
656 context
->rc_buffer_size
= 0;
658 (!codec
->fix_bitrate
? codec
->quantizer
: 2);
660 (!codec
->fix_bitrate
? codec
->quantizer
: 31);
661 context
->lmin
= 2 * FF_QP2LAMBDA
;
662 context
->lmax
= 31 * FF_QP2LAMBDA
;
663 context
->mb_lmin
= 2 * FF_QP2LAMBDA
;
664 context
->mb_lmax
= 31 * FF_QP2LAMBDA
;
665 context
->max_qdiff
= 3;
666 context
->qblur
= 0.5;
667 context
->qcompress
= 0.5;
668 // It needs the time per frame, not the frame rate.
669 context
->time_base
.den
= quicktime_frame_rate_n(file
, track
);
670 context
->time_base
.num
= quicktime_frame_rate_d(file
, track
);
672 context
->b_quant_factor
= 1.25;
673 context
->b_quant_offset
= 1.25;
674 context
->error_resilience
= FF_ER_CAREFUL
;
675 context
->error_concealment
= 3;
676 context
->frame_skip_cmp
= FF_CMP_DCTMAX
;
677 context
->ildct_cmp
= FF_CMP_VSAD
;
678 context
->intra_dc_precision
= 0;
679 context
->intra_quant_bias
= FF_DEFAULT_QUANT_BIAS
;
680 context
->inter_quant_bias
= FF_DEFAULT_QUANT_BIAS
;
681 context
->i_quant_factor
= -0.8;
682 context
->i_quant_offset
= 0.0;
683 context
->mb_decision
= FF_MB_DECISION_SIMPLE
;
684 context
->mb_cmp
= FF_CMP_SAD
;
685 context
->me_sub_cmp
= FF_CMP_SAD
;
686 context
->me_cmp
= FF_CMP_SAD
;
687 context
->me_pre_cmp
= FF_CMP_SAD
;
688 context
->me_method
= ME_EPZS
;
689 context
->me_subpel_quality
= 8;
690 context
->me_penalty_compensation
= 256;
691 context
->me_range
= 0;
692 context
->me_threshold
= 0;
693 context
->mb_threshold
= 0;
694 context
->nsse_weight
= 8;
695 context
->profile
= FF_PROFILE_UNKNOWN
;
696 context
->rc_buffer_aggressivity
= 1.0;
697 context
->level
= FF_LEVEL_UNKNOWN
;
698 context
->flags
|= CODEC_FLAG_H263P_UMV
;
699 context
->flags
|= CODEC_FLAG_AC_PRED
;
701 // All the forbidden settings can be extracted from libavcodec/mpegvideo.c of ffmpeg...
703 // Copyed from ffmpeg's mpegvideo.c... set 4MV only where it is supported
704 if(codec
->ffmpeg_id
== CODEC_ID_MPEG4
||
705 codec
->ffmpeg_id
== CODEC_ID_H263
||
706 codec
->ffmpeg_id
== CODEC_ID_H263P
||
707 codec
->ffmpeg_id
== CODEC_ID_FLV1
)
708 context
->flags
|= CODEC_FLAG_4MV
;
709 // Not compatible with Win
710 // context->flags |= CODEC_FLAG_QPEL;
713 (codec
->ffmpeg_id
== CODEC_ID_MPEG4
||
714 codec
->ffmpeg_id
== CODEC_ID_MPEG1VIDEO
||
715 codec
->ffmpeg_id
== CODEC_ID_MPEG2VIDEO
||
716 codec
->ffmpeg_id
== CODEC_ID_H263P
||
717 codec
->ffmpeg_id
== CODEC_FLAG_H263P_SLICE_STRUCT
))
719 avcodec_thread_init(context
, file
->cpus
);
720 context
->thread_count
= file
->cpus
;
723 if(!codec
->fix_bitrate
)
724 context
->flags
|= CODEC_FLAG_QSCALE
;
726 if(codec
->interlaced
)
728 context
->flags
|= CODEC_FLAG_INTERLACED_DCT
;
729 context
->flags
|= CODEC_FLAG_INTERLACED_ME
;
734 * printf("encode gop_size=%d fix_bitrate=%d quantizer=%d\n",
736 * codec->fix_bitrate,
739 avcodec_open(context
, codec
->encoder
[current_field
]);
741 avcodec_get_frame_defaults(&codec
->picture
[current_field
]);
747 if(!codec
->work_buffer
)
749 codec
->buffer_size
= width_i
* height_i
;
750 codec
->work_buffer
= malloc(codec
->buffer_size
);
756 if(codec
->use_encore
)
759 ENC_FRAME encore_input
;
760 ENC_RESULT encore_result
;
763 // Assume planes are contiguous.
764 // Encode directly from function arguments
765 if(file
->color_model
== BC_YUV420P
&&
769 encore_input
.image
= row_pointers
[0];
771 // Convert to YUV420P
772 // Encode from temporary.
775 if(!codec
->temp_frame
)
777 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
780 cmodel_transfer(0, /* Leave NULL if non existent */
782 codec
->temp_frame
, /* Leave NULL if non existent */
783 codec
->temp_frame
+ width_i
* height_i
,
784 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
785 row_pointers
[0], /* Leave NULL if non existent */
788 0, /* Dimensions to capture from input frame */
792 0, /* Dimensions to project on output frame */
798 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
799 width
, /* For planar use the luma rowspan */
803 encore_input
.image
= codec
->temp_frame
;
808 bzero(codec
->work_buffer
, codec
->buffer_size
);
809 encore_input
.bitstream
= codec
->work_buffer
;
810 encore_input
.length
= 0;
811 encore_input
.quant
= !codec
->fix_bitrate
? codec
->quantizer
: 0;
813 if(codec
->p_count
== 0)
815 codec
->p_count
[current_field
]++;
819 codec
->p_count
[current_field
]++;
820 if(codec
->p_count
[current_field
] >= codec
->max_key_interval
)
821 codec
->p_count
[current_field
] = 0;
825 encore(codec
->encode_handle
[current_field
],
830 bytes
= encore_input
.length
;
831 is_keyframe
= encore_result
.isKeyFrame
;
836 AVCodecContext
*context
= codec
->encoder_context
[current_field
];
837 AVFrame
*picture
= &codec
->picture
[current_field
];
839 if(width_i
== width
&&
840 height_i
== height
&&
841 file
->color_model
== BC_YUV420P
)
843 picture
->data
[0] = row_pointers
[0];
844 picture
->data
[1] = row_pointers
[1];
845 picture
->data
[2] = row_pointers
[2];
846 picture
->linesize
[0] = width_i
;
847 picture
->linesize
[1] = width_i
/ 2;
848 picture
->linesize
[2] = width_i
/ 2;
852 if(!codec
->temp_frame
)
854 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
857 cmodel_transfer(0, /* Leave NULL if non existent */
859 codec
->temp_frame
, /* Leave NULL if non existent */
860 codec
->temp_frame
+ width_i
* height_i
,
861 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
862 row_pointers
[0], /* Leave NULL if non existent */
865 0, /* Dimensions to capture from input frame */
869 0, /* Dimensions to project on output frame */
875 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
876 width
, /* For planar use the luma rowspan */
879 picture
->data
[0] = codec
->temp_frame
;
880 picture
->data
[1] = codec
->temp_frame
+ width_i
* height_i
;
881 picture
->data
[2] = codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4;
882 picture
->linesize
[0] = width_i
;
883 picture
->linesize
[1] = width_i
/ 2;
884 picture
->linesize
[2] = width_i
/ 2;
888 picture
->pict_type
= 0;
889 picture
->quality
= 0;
890 picture
->pts
= vtrack
->current_position
* quicktime_frame_rate_d(file
, track
);
891 picture
->key_frame
= 0;
892 bytes
= avcodec_encode_video(context
,
896 is_keyframe
= context
->coded_frame
&& context
->coded_frame
->key_frame
;
898 * printf("encode current_position=%d is_keyframe=%d\n",
899 * vtrack->current_position,
903 if(!trak
->mdia
.minf
.stbl
.stsd
.table
[0].esds
.mpeg4_header_size
&&
904 !strcmp(((quicktime_codec_t
*)vtrack
->codec
)->fourcc
, QUICKTIME_MP4V
))
906 unsigned char temp
[1024];
907 unsigned char *ptr
= temp
;
908 for(i
= 0; i
< bytes
- 4; i
++)
910 if(!(codec
->work_buffer
[i
] == 0x00 &&
911 codec
->work_buffer
[i
+ 1] == 0x00 &&
912 codec
->work_buffer
[i
+ 2] == 0x01 &&
913 codec
->work_buffer
[i
+ 3] == 0xb3))
915 *ptr
++ = codec
->work_buffer
[i
];
920 quicktime_set_mpeg4_header(&trak
->mdia
.minf
.stbl
.stsd
.table
[0],
923 trak
->mdia
.minf
.stbl
.stsd
.table
[0].version
= 0;
932 pthread_mutex_unlock(&ffmpeg_lock
);
933 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
934 result
= !quicktime_write_data(file
,
937 quicktime_write_chunk_footer(file
,
939 vtrack
->current_chunk
,
942 if(is_keyframe
|| vtrack
->current_position
== 0)
943 quicktime_insert_keyframe(file
,
944 vtrack
->current_position
,
947 vtrack
->current_chunk
++;
956 static void flush(quicktime_t
*file
, int track
)
958 quicktime_video_map_t
*track_map
= &(file
->vtracks
[track
]);
959 quicktime_trak_t
*trak
= track_map
->track
;
960 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
963 if(!trak
->mdia
.minf
.stbl
.stsd
.table
[0].esds
.mpeg4_header_size
&&
964 !strcmp(((quicktime_codec_t
*)track_map
->codec
)->fourcc
, QUICKTIME_MP4V
))
966 int width
= trak
->tkhd
.track_width
;
967 int height
= trak
->tkhd
.track_height
;
968 int width_i
= quicktime_quantize16(width
);
969 int height_i
= quicktime_quantize16(height
);
971 unsigned char temp
[1024];
972 int size
= write_mp4v_header(temp
,
975 quicktime_frame_rate(file
, track
));
976 quicktime_set_mpeg4_header(&trak
->mdia
.minf
.stbl
.stsd
.table
[0],
982 file
->moov
.udta
.require
= strdup("QuickTime 6.0 or greater");
983 file
->moov
.udta
.require_len
= strlen(file
->moov
.udta
.require
);
993 static int set_parameter(quicktime_t
*file
,
998 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
999 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
1001 if(quicktime_match_32(compressor
, QUICKTIME_DIVX
) ||
1002 quicktime_match_32(compressor
, QUICKTIME_MP42
) ||
1003 quicktime_match_32(compressor
, QUICKTIME_MPG4
) ||
1004 quicktime_match_32(compressor
, QUICKTIME_DX50
) ||
1005 quicktime_match_32(compressor
, QUICKTIME_HV60
))
1007 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1009 if(!strcasecmp(key
, "divx_bitrate"))
1010 codec
->bitrate
= *(int*)value
;
1012 if(!strcasecmp(key
, "divx_rc_period"))
1013 codec
->rc_period
= *(int*)value
;
1015 if(!strcasecmp(key
, "divx_rc_reaction_ratio"))
1016 codec
->rc_reaction_ratio
= *(int*)value
;
1018 if(!strcasecmp(key
, "divx_rc_reaction_period"))
1019 codec
->rc_reaction_period
= *(int*)value
;
1021 if(!strcasecmp(key
, "divx_max_key_interval"))
1022 codec
->max_key_interval
= *(int*)value
;
1024 if(!strcasecmp(key
, "divx_max_quantizer"))
1025 codec
->max_quantizer
= *(int*)value
;
1027 if(!strcasecmp(key
, "divx_min_quantizer"))
1028 codec
->min_quantizer
= *(int*)value
;
1030 if(!strcasecmp(key
, "divx_quantizer"))
1031 codec
->quantizer
= *(int*)value
;
1033 if(!strcasecmp(key
, "divx_quality"))
1034 codec
->quality
= *(int*)value
;
1036 if(!strcasecmp(key
, "divx_fix_bitrate"))
1037 codec
->fix_bitrate
= *(int*)value
;
1039 if(!strcasecmp(key
, "divx_use_deblocking"))
1040 codec
->use_deblocking
= *(int*)value
;
1043 if(quicktime_match_32(compressor
, QUICKTIME_DIV3
) ||
1044 quicktime_match_32(compressor
, QUICKTIME_MP4V
))
1046 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1047 if(!strcasecmp(key
, "ffmpeg_bitrate"))
1048 codec
->bitrate
= *(int*)value
;
1050 if(!strcasecmp(key
, "ffmpeg_bitrate_tolerance"))
1051 codec
->bitrate_tolerance
= *(int*)value
;
1053 if(!strcasecmp(key
, "ffmpeg_interlaced"))
1054 codec
->interlaced
= *(int*)value
;
1056 if(!strcasecmp(key
, "ffmpeg_gop_size"))
1057 codec
->gop_size
= *(int*)value
;
1059 if(!strcasecmp(key
, "ffmpeg_quantizer"))
1060 codec
->quantizer
= *(int*)value
;
1062 if(!strcasecmp(key
, "ffmpeg_fix_bitrate"))
1063 codec
->fix_bitrate
= *(int*)value
;
1070 static int delete_codec(quicktime_video_map_t
*vtrack
)
1072 quicktime_mpeg4_codec_t
*codec
;
1076 codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1077 for(i
= 0; i
< codec
->total_fields
; i
++)
1079 if(codec
->encode_initialized
[i
])
1081 pthread_mutex_lock(&ffmpeg_lock
);
1082 if(codec
->use_encore
)
1084 encore(codec
->encode_handle
[i
],
1091 avcodec_close(codec
->encoder_context
[i
]);
1092 free(codec
->encoder_context
[i
]);
1094 pthread_mutex_unlock(&ffmpeg_lock
);
1099 if(codec
->temp_frame
) free(codec
->temp_frame
);
1100 if(codec
->work_buffer
) free(codec
->work_buffer
);
1101 if(codec
->decoder
) quicktime_delete_ffmpeg(codec
->decoder
);
1110 static quicktime_mpeg4_codec_t
* init_common(quicktime_video_map_t
*vtrack
,
1115 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
1116 quicktime_mpeg4_codec_t
*codec
;
1118 codec_base
->priv
= calloc(1, sizeof(quicktime_mpeg4_codec_t
));
1119 codec_base
->delete_vcodec
= delete_codec
;
1120 codec_base
->decode_video
= decode
;
1121 codec_base
->encode_video
= encode
;
1122 codec_base
->flush
= flush
;
1123 codec_base
->reads_colormodel
= reads_colormodel
;
1124 codec_base
->writes_colormodel
= writes_colormodel
;
1125 codec_base
->set_parameter
= set_parameter
;
1126 codec_base
->fourcc
= compressor
;
1127 codec_base
->title
= title
;
1128 codec_base
->desc
= description
;
1130 codec
= (quicktime_mpeg4_codec_t
*)codec_base
->priv
;
1135 codec
->bitrate
= 1000000;
1136 codec
->rc_period
= 50;
1137 codec
->rc_reaction_ratio
= 45;
1138 codec
->rc_reaction_period
= 10;
1139 codec
->max_key_interval
= 45;
1140 codec
->max_quantizer
= 31;
1141 codec
->min_quantizer
= 1;
1142 codec
->quantizer
= 10;
1144 codec
->fix_bitrate
= 1;
1145 codec
->total_fields
= 1;
1155 // Mike Rowe Soft MPEG-4
1156 void quicktime_init_codec_div3(quicktime_video_map_t
*vtrack
)
1158 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1161 "Mike Row Soft MPEG4 Version 3");
1162 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1165 void quicktime_init_codec_div5(quicktime_video_map_t
*vtrack
)
1167 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1170 "Mike Row Soft MPEG4 Version 5");
1171 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1174 // Mike Rowe Soft MPEG-4
1175 void quicktime_init_codec_div3lower(quicktime_video_map_t
*vtrack
)
1177 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1178 QUICKTIME_DIV3_LOWER
,
1180 "Mike Row Soft MPEG4 Version 3");
1181 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1184 void quicktime_init_codec_div3v2(quicktime_video_map_t
*vtrack
)
1186 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1189 "Mike Row Soft MPEG4 Version 2");
1190 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V2
;
1194 void quicktime_init_codec_divx(quicktime_video_map_t
*vtrack
)
1196 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1199 "Generic MPEG Four");
1200 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1201 result
->use_encore
= 1;
1204 void quicktime_init_codec_mpg4(quicktime_video_map_t
*vtrack
)
1206 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1209 "FFMPEG (msmpeg4)");
1210 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V1
;
1213 void quicktime_init_codec_dx50(quicktime_video_map_t
*vtrack
)
1215 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1219 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1223 void quicktime_init_codec_mp4v(quicktime_video_map_t
*vtrack
)
1225 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1228 "Generic MPEG Four");
1229 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1230 // result->use_encore = 1;
1235 void quicktime_init_codec_svq1(quicktime_video_map_t
*vtrack
)
1237 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1239 "Sorenson Version 1",
1240 "From the chearch of codecs of yesterday's sights");
1241 result
->ffmpeg_id
= CODEC_ID_SVQ1
;
1244 void quicktime_init_codec_svq3(quicktime_video_map_t
*vtrack
)
1246 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1248 "Sorenson Version 3",
1249 "From the chearch of codecs of yesterday's sights");
1250 result
->ffmpeg_id
= CODEC_ID_SVQ3
;
1253 void quicktime_init_codec_h263(quicktime_video_map_t
*vtrack
)
1255 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1259 result
->ffmpeg_id
= CODEC_ID_H263
;
1262 void quicktime_init_codec_xvid(quicktime_video_map_t
*vtrack
)
1264 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1268 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1271 // field based MPEG-4
1272 void quicktime_init_codec_hv60(quicktime_video_map_t
*vtrack
)
1274 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1277 "MPEG 4 with alternating streams every other frame. (Not standardized)");
1278 result
->total_fields
= 2;
1279 result
->ffmpeg_id
= CODEC_ID_MPEG4
;