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. */
10 #include <ffmpeg/avcodec.h>
11 #include "colormodels.h"
12 #include "funcprotos.h"
13 #include "quicktime.h"
14 #include "workarounds.h"
15 #include ENCORE_INCLUDE
16 //#include DECORE_INCLUDE
24 #define FRAME_RATE_BASE 10000
30 int decode_initialized
[FIELDS
];
34 AVCodec
*decoder
[FIELDS
];
35 AVCodecContext
*decoder_context
[FIELDS
];
36 AVFrame picture
[FIELDS
];
40 // DEC_PARAM dec_param[FIELDS];
41 // int decode_handle[FIELDS];
44 long last_frame
[FIELDS
];
57 int encode_initialized
[FIELDS
];
58 // Information for picking the right library routines.
59 // ID out of avcodec.h for the codec used.
60 // Invalid if encore50 is used.
62 // True if encore50 is being used.
66 AVCodec
*encoder
[FIELDS
];
67 AVCodecContext
*encoder_context
[FIELDS
];
71 int encode_handle
[FIELDS
];
72 ENC_PARAM enc_param
[FIELDS
];
73 // Must count pframes in VBR
77 // Encoding parameters
79 // For heroine 60 encoding, we want different streams for each field.
81 long rc_period
; // the intended rate control averaging period
82 long rc_reaction_period
; // the reation period for rate control
83 long rc_reaction_ratio
; // the ratio for down/up rate control
84 long max_key_interval
; // the maximum interval between key frames
85 int bitrate_tolerance
;
88 int max_quantizer
; // the upper limit of the quantizer
89 int min_quantizer
; // the lower limit of the quantizer
90 int quantizer
; // For vbr
91 int quality
; // the forward search range for motion estimation
96 // Temporary storage for color conversions
98 // Storage of compressed data
99 unsigned char *work_buffer
;
100 // Allocation of work_buffer
102 } quicktime_mpeg4_codec_t
;
104 int ffmpeg_initialized
= 0;
105 pthread_mutex_t ffmpeg_lock
= PTHREAD_MUTEX_INITIALIZER
;
108 // Decore needs the user to specify handles
109 static int decode_handle
= 1;
110 static int encode_handle
= 0;
120 // Utilities for programs wishing to parse MPEG-4
123 // Determine of the compressed frame is a keyframe for direct copy
124 int quicktime_mpeg4_is_key(unsigned char *data
, long size
, char *codec_id
)
129 if(quicktime_match_32(codec_id
, QUICKTIME_DIVX
) ||
130 quicktime_match_32(codec_id
, QUICKTIME_HV60
))
132 for(i
= 0; i
< size
- 5; i
++)
134 if( data
[i
] == 0x00 &&
135 data
[i
+ 1] == 0x00 &&
136 data
[i
+ 2] == 0x01 &&
139 if((data
[i
+ 4] & 0xc0) == 0x0)
150 // Test for VOL header in frame
151 int quicktime_mpeg4_has_vol(unsigned char *data
)
153 if( data
[0] == 0x00 &&
169 static void putbits(unsigned char **data
,
176 value
&= 0xffffffffffffffffLL
>> (64 - count
);
178 while(64 - *bit_pos
< count
)
180 *(*data
)++ = (*bit_store
) >> 56;
185 (*bit_store
) |= value
<< (64 - count
- *bit_pos
);
191 static void flushbits(unsigned char **data
,
195 //printf("flushbits %llx\n", (*bit_store));
196 while((*bit_pos
) > 0)
198 *(*data
)++ = (*bit_store
) >> 56;
207 #define VO_START_CODE 0x8
208 #define VO_START_CODE_LENGTH 27
209 #define VOL_START_CODE 0x12 /* 25-MAR-97 JDL : according to WD2 */
210 #define VOL_START_CODE_LENGTH 28
214 int quicktime_mpeg4_write_vol(unsigned char *data_start
,
217 int time_increment_resolution
,
221 int bits
, fixed_vop_time_increment
;
222 unsigned char *data
= data_start
;
229 vol_width
= (int)((float)vol_width
/ 16 + 0.5) * 16;
230 vol_height
= (int)((float)vol_height
/ 16 + 0.5) * 16;
237 VO_START_CODE_LENGTH
, VO_START_CODE
);
242 5, 0); /* vo_id = 0 */
248 VOL_START_CODE_LENGTH
, VOL_START_CODE
);
257 4, 0); /* vol_id = 0 */
263 1, 0); /* random_accessible_vol = 0 */
268 8, 1); /* video_object_type_indication = 1 video */
273 1, 1); /* is_object_layer_identifier = 1 */
278 4, 2); /* visual_object_layer_ver_id = 2 */
283 3, 1); /* visual_object_layer_priority = 1 */
288 4, 1); /* aspect_ratio_info = 1 */
300 1, 0); /* vol_control_parameter = 0 */
305 2, 0); /* vol_shape = 0 rectangular */
322 16, time_increment_resolution
);
332 1, 1); /* fixed_vop_rate = 1 */
336 while((1 << bits
) < time_increment_resolution
) bits
++;
338 // Log calculation fails for some reason
339 // bits = (int)ceil(log((double)time_increment_resolution) / log(2.0));
340 // if (bits < 1) bits=1;
342 fixed_vop_time_increment
=
343 (int)(time_increment_resolution
/ frame_rate
+ 0.1);
349 bits
, fixed_vop_time_increment
);
382 1, 0); /* interlaced = 0 */
387 1, 1); /* OBMC_disabled = 1 */
392 2, 0); /* vol_sprite_usage = 0 */
397 1, 0); /* not_8_bit = 0 */
403 1, 0); /* vol_quant_type = 0 */
408 1, 0); /* vol_quarter_pixel = 0 */
413 1, 1); /* complexity_estimation_disabled = 1 */
418 1, 1); /* resync_marker_disabled = 1 */
423 1, 0); /* data_partitioning_enabled = 0 */
428 1, 0); /* scalability = 0 */
437 * for(i = 0; i < data - data_start; i++)
438 * for(j = 0x80; j >= 1; j /= 2)
439 * printf("%d", (data_start[i] & j) ? 1 : 0);
445 return data
- data_start
;
450 // Create the header for the esds block which is used in mp4v.
451 // Taken from libavcodec
453 static int write_mp4v_header(unsigned char *data
,
458 unsigned char *start
= data
;
459 // Advanced simple level 1
460 int profile_level
= 0xf3;
461 int vo_version_id
= 5;
472 *data
++ = profile_level
;
474 // Visual object startcode
479 *data
++ = (1 << 7) ||
480 (vo_version_id
<< 3) ||
483 // visual object type
484 *data
++ = (1 << 4) ||
492 int vol_size
= quicktime_mpeg4_write_vol(data
,
510 static int reads_colormodel(quicktime_t
*file
,
514 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
515 quicktime_codec_t
*codec
= (quicktime_codec_t
*)vtrack
->codec
;
516 return (colormodel
== BC_YUV420P
&&
517 !quicktime_match_32(QUICKTIME_SVQ1
, codec
->fourcc
));
520 static int writes_colormodel(quicktime_t
*file
,
524 return (colormodel
== BC_RGB888
||
525 colormodel
== BC_RGBA8888
||
526 colormodel
== BC_RGB161616
||
527 colormodel
== BC_RGBA16161616
||
528 colormodel
== BC_YUV888
||
529 colormodel
== BC_YUVA8888
||
530 colormodel
== BC_YUV161616
||
531 colormodel
== BC_YUVA16161616
||
532 colormodel
== BC_YUV420P
||
533 colormodel
== BC_YUV422
||
534 colormodel
== BC_COMPRESSED
);
538 static int delete_decoder(quicktime_mpeg4_codec_t
*codec
, int field
)
540 if(codec
->decode_initialized
[field
])
542 pthread_mutex_lock(&ffmpeg_lock
);
544 avcodec_close(codec
->decoder_context
[field
]);
545 free(codec
->decoder_context
[field
]);
547 pthread_mutex_unlock(&ffmpeg_lock
);
548 codec
->decode_initialized
[field
] = 0;
553 static int init_decode(quicktime_mpeg4_codec_t
*codec
,
559 if(!ffmpeg_initialized
)
561 ffmpeg_initialized
= 1;
563 avcodec_register_all();
567 codec
->decoder
[current_field
] = avcodec_find_decoder(codec
->ffmpeg_id
);
568 if(!codec
->decoder
[current_field
])
570 printf("init_decode: avcodec_find_decoder returned NULL.\n");
574 codec
->decoder_context
[current_field
] = avcodec_alloc_context();
575 codec
->decoder_context
[current_field
]->width
= width_i
;
576 codec
->decoder_context
[current_field
]->height
= height_i
;
577 if(avcodec_open(codec
->decoder_context
[current_field
],
578 codec
->decoder
[current_field
]) < 0)
580 printf("init_decode: avcodec_open failed.\n");
586 static int decode_wrapper(quicktime_t
*file
,
587 quicktime_video_map_t
*vtrack
,
588 quicktime_mpeg4_codec_t
*codec
,
597 int header_bytes
= 0;
598 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
599 quicktime_trak_t
*trak
= vtrack
->track
;
600 quicktime_stsd_table_t
*stsd_table
= &trak
->mdia
.minf
.stbl
.stsd
.table
[0];
601 int width
= trak
->tkhd
.track_width
;
602 int height
= trak
->tkhd
.track_height
;
603 int width_i
= (int)((float)width
/ 16 + 0.5) * 16;
604 int height_i
= (int)((float)height
/ 16 + 0.5) * 16;
606 quicktime_set_video_position(file
, frame_number
, track
);
608 bytes
= quicktime_frame_size(file
, frame_number
, track
);
609 if(frame_number
== 0)
611 header_bytes
= stsd_table
->mpeg4_header_size
;
613 //printf("decode_wrapper 1 %p %d %d %d\n", stsd_table, frame_number, bytes, header_bytes);
615 if(!codec
->work_buffer
|| codec
->buffer_size
< bytes
+ header_bytes
)
617 if(codec
->work_buffer
) free(codec
->work_buffer
);
618 codec
->buffer_size
= bytes
+ header_bytes
;
619 codec
->work_buffer
= calloc(1, codec
->buffer_size
+ 100);
623 memcpy(codec
->work_buffer
, stsd_table
->mpeg4_header
, header_bytes
);
625 //printf("decode_wrapper 1 %d %d\n", header_bytes, bytes);
626 if(!quicktime_read_data(file
,
627 codec
->work_buffer
+ header_bytes
,
635 * if(!codec->got_key[current_field])
637 * if(!quicktime_mpeg4_is_key(codec->work_buffer, bytes, compressor))
641 * codec->got_key[current_field] = 1;
647 // No way to determine if there was an error based on nonzero status.
648 // Need to test row pointers to determine if an error occurred.
649 result
= avcodec_decode_video(codec
->decoder_context
[current_field
],
650 &codec
->picture
[current_field
],
653 bytes
+ header_bytes
);
657 if(codec
->picture
[current_field
].data
[0])
659 if(!codec
->got_key
[current_field
])
661 codec
->got_key
[current_field
] = 1;
667 // ffmpeg can't recover if the first frame errored out, like in a direct copy
670 * delete_decoder(codec, current_field);
671 * init_decode(codec, current_field, width_i, height_i);
684 static int decode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
688 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
689 quicktime_trak_t
*trak
= vtrack
->track
;
690 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
691 int width
= trak
->tkhd
.track_width
;
692 int height
= trak
->tkhd
.track_height
;
697 int current_field
= vtrack
->current_position
% codec
->total_fields
;
698 unsigned char **input_rows
;
699 int seeking_done
= 0;
701 if(codec
->ffmpeg_id
== CODEC_ID_SVQ1
)
703 width_i
= (int)((float)width
/ 16 + 0.5) * 32;
704 height_i
= (int)((float)height
/ 16 + 0.5) * 32;
708 width_i
= (int)((float)width
/ 16 + 0.5) * 16;
709 height_i
= (int)((float)height
/ 16 + 0.5) * 16;
712 pthread_mutex_lock(&ffmpeg_lock
);
715 if(!codec
->decode_initialized
[current_field
])
717 int current_frame
= vtrack
->current_position
;
718 init_decode(codec
, current_field
, width_i
, height_i
);
719 // Must decode frame with stream header first but only the first frame in the
720 // field sequence has a stream header.
721 result
= decode_wrapper(file
,
727 // Reset position because decode wrapper set it
728 quicktime_set_video_position(file
, current_frame
, track
);
729 codec
->decode_initialized
[current_field
] = 1;
733 if(quicktime_has_keyframes(file
, track
) &&
734 vtrack
->current_position
!= codec
->last_frame
[current_field
] + codec
->total_fields
)
736 int frame1
, frame2
= vtrack
->current_position
, current_frame
= frame2
;
738 //printf("decode 2\n");
740 // Get first keyframe of same field
743 frame1
= quicktime_get_keyframe_before(file
,
746 }while(frame1
> 0 && (frame1
% codec
->total_fields
) != current_field
);
747 //printf("decode 3\n");
749 // Keyframe is before last decoded frame and current frame is after last decoded
750 // frame, so instead of rerendering from the last keyframe we can rerender from
751 // the last decoded frame.
752 if(frame1
< codec
->last_frame
[current_field
] &&
753 frame2
> codec
->last_frame
[current_field
])
755 //printf("decode 1 %d %d\n", frame1, frame2);
756 frame1
= codec
->last_frame
[current_field
] + codec
->total_fields
;
760 while(frame1
<= frame2
)
762 result
= decode_wrapper(file
,
770 // May need to do the first I frame twice.
773 result
= decode_wrapper(file
,
781 frame1
+= codec
->total_fields
;
784 vtrack
->current_position
= frame2
;
791 result
= decode_wrapper(file
,
794 vtrack
->current_position
,
798 pthread_mutex_unlock(&ffmpeg_lock
);
802 codec
->last_frame
[current_field
] = vtrack
->current_position
;
812 // result = (result != 0);
813 switch(codec
->decoder_context
[current_field
]->pix_fmt
)
815 case PIX_FMT_YUV420P
:
816 input_cmodel
= BC_YUV420P
;
819 input_cmodel
= BC_YUV422
;
821 case PIX_FMT_YUV422P
:
822 input_cmodel
= BC_YUV422P
;
824 case PIX_FMT_YUV410P
:
825 input_cmodel
= BC_YUV9P
;
829 "mpeg4 decode: unrecognized color model %d\n",
830 codec
->decoder_context
[current_field
]->pix_fmt
);
831 input_cmodel
= BC_YUV420P
;
839 if(codec
->picture
[current_field
].data
[0])
843 malloc(sizeof(unsigned char*) *
844 codec
->decoder_context
[current_field
]->height
);
847 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
++)
848 input_rows
[i
] = codec
->picture
[current_field
].data
[0] +
850 codec
->decoder_context
[current_field
]->width
*
851 cmodel_calculate_pixelsize(input_cmodel
);
854 cmodel_transfer(row_pointers
, /* Leave NULL if non existent */
856 row_pointers
[0], /* Leave NULL if non existent */
859 codec
->picture
[current_field
].data
[0], /* Leave NULL if non existent */
860 codec
->picture
[current_field
].data
[1],
861 codec
->picture
[current_field
].data
[2],
862 file
->in_x
, /* Dimensions to capture from input frame */
866 0, /* Dimensions to project on output frame */
872 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
873 codec
->picture
[current_field
].linesize
[0], /* For planar use the luma rowspan */
885 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
887 int64_t offset
= quicktime_position(file
);
888 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
889 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
890 quicktime_trak_t
*trak
= vtrack
->track
;
891 int width
= trak
->tkhd
.track_width
;
892 int height
= trak
->tkhd
.track_height
;
893 int width_i
= (int)((float)width
/ 16 + 0.5) * 16;
894 int height_i
= (int)((float)height
/ 16 + 0.5) * 16;
899 int current_field
= vtrack
->current_position
% codec
->total_fields
;
900 quicktime_atom_t chunk_atom
;
903 //printf("encode 1\n");
907 pthread_mutex_lock(&ffmpeg_lock
);
911 if(!codec
->encode_initialized
[current_field
])
914 if(codec
->ffmpeg_id
== CODEC_ID_MPEG4
)
916 codec
->use_encore
= 1;
917 codec
->encode_initialized
[current_field
] = 1;
918 codec
->encode_handle
[current_field
] = encode_handle
++;
919 codec
->enc_param
[current_field
].x_dim
= width_i
;
920 codec
->enc_param
[current_field
].y_dim
= height_i
;
921 codec
->enc_param
[current_field
].framerate
=
922 quicktime_frame_rate(file
, track
) / codec
->total_fields
;
923 codec
->enc_param
[current_field
].bitrate
=
924 codec
->bitrate
/ codec
->total_fields
;
925 codec
->enc_param
[current_field
].rc_period
= codec
->rc_period
;
926 codec
->enc_param
[current_field
].rc_reaction_period
= codec
->rc_reaction_period
;
927 codec
->enc_param
[current_field
].rc_reaction_ratio
= codec
->rc_reaction_ratio
;
928 codec
->enc_param
[current_field
].max_quantizer
= codec
->max_quantizer
;
929 codec
->enc_param
[current_field
].min_quantizer
= codec
->min_quantizer
;
930 codec
->enc_param
[current_field
].max_key_interval
= codec
->max_key_interval
;
932 codec
->enc_param
[current_field
].search_range
= codec
->quality
* 3;
933 if(codec
->enc_param
[current_field
].search_range
> 15)
934 codec
->enc_param
[current_field
].search_range
= 15;
936 encore(codec
->encode_handle
[current_field
],
938 &codec
->enc_param
[current_field
], NULL
);
941 // Create esds header
942 if(!strcmp(((quicktime_codec_t
*)vtrack
->codec
)->fourcc
, QUICKTIME_MP4V
))
944 unsigned char temp
[256];
945 int size
= write_mp4v_header(temp
,
948 quicktime_frame_rate(file
, track
));
949 quicktime_set_mpeg4_header(&trak
->mdia
.minf
.stbl
.stsd
.table
[0],
957 static char *video_rc_eq
="tex^qComp";
958 codec
->encode_initialized
[current_field
] = 1;
959 if(!ffmpeg_initialized
)
961 ffmpeg_initialized
= 1;
963 avcodec_register_all();
966 codec
->encoder
[current_field
] = avcodec_find_encoder(codec
->ffmpeg_id
);
967 if(!codec
->encoder
[current_field
])
969 printf("encode: avcodec_find_encoder returned NULL.\n");
970 pthread_mutex_unlock(&ffmpeg_lock
);
974 codec
->encoder_context
[current_field
] = avcodec_alloc_context();
975 codec
->encoder_context
[current_field
]->frame_rate
= FRAME_RATE_BASE
*
976 quicktime_frame_rate(file
, track
);
977 codec
->encoder_context
[current_field
]->width
= width_i
;
978 codec
->encoder_context
[current_field
]->height
= height_i
;
979 codec
->encoder_context
[current_field
]->gop_size
= codec
->gop_size
;
980 codec
->encoder_context
[current_field
]->pix_fmt
= PIX_FMT_YUV420P
;
981 codec
->encoder_context
[current_field
]->bit_rate
= codec
->bitrate
;
982 codec
->encoder_context
[current_field
]->bit_rate_tolerance
= codec
->bitrate_tolerance
;
983 codec
->encoder_context
[current_field
]->rc_eq
= video_rc_eq
;
984 codec
->encoder_context
[current_field
]->qmin
= 2;
985 codec
->encoder_context
[current_field
]->qmax
= 31;
986 codec
->encoder_context
[current_field
]->max_qdiff
= 3;
987 codec
->encoder_context
[current_field
]->qblur
= 0.5;
988 codec
->encoder_context
[current_field
]->qcompress
= 0.5;
989 codec
->encoder_context
[current_field
]->me_method
= ME_FULL
;
991 printf("encode %d %d %d %d %d\n", codec
->gop_size
, codec
->bitrate
, codec
->bitrate_tolerance
, codec
->fix_bitrate
, codec
->interlaced
);
994 if(!codec
->fix_bitrate
)
996 codec
->encoder_context
[current_field
]->flags
|= CODEC_FLAG_QSCALE
;
999 if(codec
->interlaced
)
1001 codec
->encoder_context
[current_field
]->flags
|= CODEC_FLAG_INTERLACED_DCT
;
1004 avcodec_open(codec
->encoder_context
[current_field
], codec
->encoder
[current_field
]);
1010 if(!codec
->work_buffer
)
1012 codec
->buffer_size
= width_i
* height_i
;
1013 codec
->work_buffer
= malloc(codec
->buffer_size
);
1019 if(codec
->use_encore
)
1022 ENC_FRAME encore_input
;
1023 ENC_RESULT encore_result
;
1026 // Assume planes are contiguous.
1027 // Encode directly from function arguments
1028 if(file
->color_model
== BC_YUV420P
&&
1032 encore_input
.image
= row_pointers
[0];
1034 // Convert to YUV420P
1035 // Encode from temporary.
1038 if(!codec
->temp_frame
)
1040 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
1043 cmodel_transfer(0, /* Leave NULL if non existent */
1045 codec
->temp_frame
, /* Leave NULL if non existent */
1046 codec
->temp_frame
+ width_i
* height_i
,
1047 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1048 row_pointers
[0], /* Leave NULL if non existent */
1051 0, /* Dimensions to capture from input frame */
1055 0, /* Dimensions to project on output frame */
1061 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1062 width
, /* For planar use the luma rowspan */
1066 encore_input
.image
= codec
->temp_frame
;
1071 bzero(codec
->work_buffer
, codec
->buffer_size
);
1072 encore_input
.bitstream
= codec
->work_buffer
;
1073 encore_input
.length
= 0;
1074 encore_input
.quant
= !codec
->fix_bitrate
? codec
->quantizer
: 0;
1076 if(codec
->p_count
== 0)
1078 codec
->p_count
[current_field
]++;
1082 codec
->p_count
[current_field
]++;
1083 if(codec
->p_count
[current_field
] >= codec
->max_key_interval
)
1084 codec
->p_count
[current_field
] = 0;
1087 encore(codec
->encode_handle
[current_field
],
1092 bytes
= encore_input
.length
;
1093 is_keyframe
= encore_result
.isKeyFrame
;
1100 if(width_i
== width
&&
1101 height_i
== height
&&
1102 file
->color_model
== BC_YUV420P
)
1104 pict_tmp
.data
[0] = row_pointers
[0];
1105 pict_tmp
.data
[1] = row_pointers
[1];
1106 pict_tmp
.data
[2] = row_pointers
[2];
1107 pict_tmp
.linesize
[0] = width_i
;
1108 pict_tmp
.linesize
[1] = width_i
/ 2;
1109 pict_tmp
.linesize
[2] = width_i
/ 2;
1113 if(!codec
->temp_frame
)
1115 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
1118 cmodel_transfer(0, /* Leave NULL if non existent */
1120 codec
->temp_frame
, /* Leave NULL if non existent */
1121 codec
->temp_frame
+ width_i
* height_i
,
1122 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1123 row_pointers
[0], /* Leave NULL if non existent */
1126 0, /* Dimensions to capture from input frame */
1130 0, /* Dimensions to project on output frame */
1136 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1137 width
, /* For planar use the luma rowspan */
1140 pict_tmp
.data
[0] = codec
->temp_frame
;
1141 pict_tmp
.data
[1] = codec
->temp_frame
+ width_i
* height_i
;
1142 pict_tmp
.data
[2] = codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4;
1143 pict_tmp
.linesize
[0] = width_i
;
1144 pict_tmp
.linesize
[1] = width_i
/ 2;
1145 pict_tmp
.linesize
[2] = width_i
/ 2;
1149 if(codec
->quantizer
>= 0)
1150 pict_tmp
.quality
= codec
->quantizer
;
1151 bytes
= avcodec_encode_video(codec
->encoder_context
[current_field
],
1155 is_keyframe
= pict_tmp
.key_frame
;
1163 pthread_mutex_unlock(&ffmpeg_lock
);
1164 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
1165 result
= !quicktime_write_data(file
,
1168 quicktime_write_chunk_footer(file
,
1170 vtrack
->current_chunk
,
1174 quicktime_insert_keyframe(file
,
1175 vtrack
->current_position
,
1177 //printf("encode 10\n");
1179 vtrack
->current_chunk
++;
1189 static int set_parameter(quicktime_t
*file
,
1194 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
1195 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
1197 if(quicktime_match_32(compressor
, QUICKTIME_DIVX
) ||
1198 quicktime_match_32(compressor
, QUICKTIME_HV60
))
1200 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1202 if(!strcasecmp(key
, "divx_bitrate"))
1203 codec
->bitrate
= *(int*)value
;
1205 if(!strcasecmp(key
, "divx_rc_period"))
1206 codec
->rc_period
= *(int*)value
;
1208 if(!strcasecmp(key
, "divx_rc_reaction_ratio"))
1209 codec
->rc_reaction_ratio
= *(int*)value
;
1211 if(!strcasecmp(key
, "divx_rc_reaction_period"))
1212 codec
->rc_reaction_period
= *(int*)value
;
1214 if(!strcasecmp(key
, "divx_max_key_interval"))
1215 codec
->max_key_interval
= *(int*)value
;
1217 if(!strcasecmp(key
, "divx_max_quantizer"))
1218 codec
->max_quantizer
= *(int*)value
;
1220 if(!strcasecmp(key
, "divx_min_quantizer"))
1221 codec
->min_quantizer
= *(int*)value
;
1223 if(!strcasecmp(key
, "divx_quantizer"))
1224 codec
->quantizer
= *(int*)value
;
1226 if(!strcasecmp(key
, "divx_quality"))
1227 codec
->quality
= *(int*)value
;
1229 if(!strcasecmp(key
, "divx_fix_bitrate"))
1230 codec
->fix_bitrate
= *(int*)value
;
1232 if(!strcasecmp(key
, "divx_use_deblocking"))
1233 codec
->use_deblocking
= *(int*)value
;
1236 if(quicktime_match_32(compressor
, QUICKTIME_DIV3
))
1238 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1239 if(!strcasecmp(key
, "div3_bitrate"))
1240 codec
->bitrate
= *(int*)value
;
1242 if(!strcasecmp(key
, "div3_bitrate_tolerance"))
1243 codec
->bitrate_tolerance
= *(int*)value
;
1245 if(!strcasecmp(key
, "div3_interlaced"))
1246 codec
->interlaced
= *(int*)value
;
1248 if(!strcasecmp(key
, "div3_gop_size"))
1249 codec
->gop_size
= *(int*)value
;
1251 if(!strcasecmp(key
, "div3_quantizer"))
1252 codec
->quantizer
= *(int*)value
;
1254 if(!strcasecmp(key
, "div3_fix_bitrate"))
1255 codec
->fix_bitrate
= *(int*)value
;
1262 static int delete_codec(quicktime_video_map_t
*vtrack
)
1264 quicktime_mpeg4_codec_t
*codec
;
1268 codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1269 for(i
= 0; i
< codec
->total_fields
; i
++)
1271 if(codec
->encode_initialized
[i
])
1273 pthread_mutex_lock(&ffmpeg_lock
);
1274 if(codec
->use_encore
)
1276 encore(codec
->encode_handle
[i
],
1283 avcodec_close(codec
->encoder_context
[i
]);
1284 free(codec
->encoder_context
[i
]);
1286 pthread_mutex_unlock(&ffmpeg_lock
);
1288 delete_decoder(codec
, i
);
1292 if(codec
->temp_frame
) free(codec
->temp_frame
);
1293 if(codec
->work_buffer
) free(codec
->work_buffer
);
1303 static quicktime_mpeg4_codec_t
* init_common(quicktime_video_map_t
*vtrack
,
1308 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
1309 quicktime_mpeg4_codec_t
*codec
;
1311 codec_base
->priv
= calloc(1, sizeof(quicktime_mpeg4_codec_t
));
1312 codec_base
->delete_vcodec
= delete_codec
;
1313 codec_base
->decode_video
= decode
;
1314 codec_base
->encode_video
= encode
;
1315 codec_base
->reads_colormodel
= reads_colormodel
;
1316 codec_base
->writes_colormodel
= writes_colormodel
;
1317 codec_base
->set_parameter
= set_parameter
;
1318 codec_base
->fourcc
= compressor
;
1319 codec_base
->title
= title
;
1320 codec_base
->desc
= description
;
1322 codec
= (quicktime_mpeg4_codec_t
*)codec_base
->priv
;
1327 codec
->bitrate
= 1000000;
1328 codec
->rc_period
= 50;
1329 codec
->rc_reaction_ratio
= 45;
1330 codec
->rc_reaction_period
= 10;
1331 codec
->max_key_interval
= 45;
1332 codec
->max_quantizer
= 31;
1333 codec
->min_quantizer
= 1;
1334 codec
->quantizer
= 10;
1336 codec
->fix_bitrate
= 1;
1337 codec
->total_fields
= 1;
1347 // Mike Rowe Soft MPEG-4
1348 void quicktime_init_codec_div3(quicktime_video_map_t
*vtrack
)
1350 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1353 "Mike Row Soft MPEG4 Version 3");
1354 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1357 // Mike Rowe Soft MPEG-4
1358 void quicktime_init_codec_div3lower(quicktime_video_map_t
*vtrack
)
1360 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1361 QUICKTIME_DIV3_LOWER
,
1363 "Mike Row Soft MPEG4 Version 3");
1364 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1369 void quicktime_init_codec_divx(quicktime_video_map_t
*vtrack
)
1371 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1374 "Generic MPEG Four");
1375 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1379 void quicktime_init_codec_mp4v(quicktime_video_map_t
*vtrack
)
1381 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1384 "Generic MPEG Four");
1385 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1390 void quicktime_init_codec_svq1(quicktime_video_map_t
*vtrack
)
1392 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1394 "Sorenson Version 1",
1395 "From the chearch of codecs of yesterday's sights");
1396 result
->ffmpeg_id
= CODEC_ID_SVQ1
;
1399 void quicktime_init_codec_svq3(quicktime_video_map_t
*vtrack
)
1401 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1403 "Sorenson Version 3",
1404 "From the chearch of codecs of yesterday's sights");
1405 result
->ffmpeg_id
= CODEC_ID_SVQ3
;
1408 void quicktime_init_codec_h263(quicktime_video_map_t
*vtrack
)
1410 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1414 result
->ffmpeg_id
= CODEC_ID_H263
;
1417 // field based MPEG-4
1418 void quicktime_init_codec_hv60(quicktime_video_map_t
*vtrack
)
1420 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1423 "MPEG 4 with alternating streams every other frame. (Not standardized)");
1424 result
->total_fields
= 2;
1425 result
->ffmpeg_id
= CODEC_ID_MPEG4
;