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"
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
;
456 static int reads_colormodel(quicktime_t
*file
,
460 return (colormodel
== BC_YUV420P
);
463 static int writes_colormodel(quicktime_t
*file
,
467 return (colormodel
== BC_RGB888
||
468 colormodel
== BC_RGBA8888
||
469 colormodel
== BC_RGB161616
||
470 colormodel
== BC_RGBA16161616
||
471 colormodel
== BC_YUV888
||
472 colormodel
== BC_YUVA8888
||
473 colormodel
== BC_YUV161616
||
474 colormodel
== BC_YUVA16161616
||
475 colormodel
== BC_YUV420P
||
476 colormodel
== BC_YUV422
||
477 colormodel
== BC_COMPRESSED
);
481 static int delete_decoder(quicktime_mpeg4_codec_t
*codec
, int field
)
483 if(codec
->decode_initialized
[field
])
485 pthread_mutex_lock(&ffmpeg_lock
);
487 avcodec_close(codec
->decoder_context
[field
]);
488 free(codec
->decoder_context
[field
]);
490 pthread_mutex_unlock(&ffmpeg_lock
);
491 codec
->decode_initialized
[field
] = 0;
496 static int init_decode(quicktime_mpeg4_codec_t
*codec
,
502 if(!ffmpeg_initialized
)
504 ffmpeg_initialized
= 1;
506 avcodec_register_all();
510 codec
->decoder
[current_field
] = avcodec_find_decoder(codec
->ffmpeg_id
);
511 if(!codec
->decoder
[current_field
])
513 printf("init_decode: avcodec_find_decoder returned NULL.\n");
517 codec
->decoder_context
[current_field
] = avcodec_alloc_context();
518 codec
->decoder_context
[current_field
]->width
= width_i
;
519 codec
->decoder_context
[current_field
]->height
= height_i
;
520 if(avcodec_open(codec
->decoder_context
[current_field
],
521 codec
->decoder
[current_field
]) < 0)
523 printf("init_decode: avcodec_open failed.\n");
530 static int decode_wrapper(quicktime_t
*file
,
531 quicktime_video_map_t
*vtrack
,
532 quicktime_mpeg4_codec_t
*codec
,
540 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
541 quicktime_trak_t
*trak
= vtrack
->track
;
542 int width
= trak
->tkhd
.track_width
;
543 int height
= trak
->tkhd
.track_height
;
544 int width_i
= (int)((float)width
/ 16 + 0.5) * 16;
545 int height_i
= (int)((float)height
/ 16 + 0.5) * 16;
547 //printf("decode_wrapper 1\n");
548 quicktime_set_video_position(file
, frame_number
, track
);
550 bytes
= quicktime_frame_size(file
, frame_number
, track
);
552 if(!codec
->work_buffer
|| codec
->buffer_size
< bytes
)
554 if(codec
->work_buffer
) free(codec
->work_buffer
);
555 codec
->buffer_size
= bytes
;
556 codec
->work_buffer
= calloc(1, codec
->buffer_size
+ 100);
559 //printf("decode_wrapper 1 %d %llx %x\n", codec->ffmpeg_id, quicktime_position(file), bytes);
560 if(!quicktime_read_data(file
,
569 * if(!codec->got_key[current_field])
571 * if(!quicktime_mpeg4_is_key(codec->work_buffer, bytes, compressor))
575 * codec->got_key[current_field] = 1;
580 //printf("decode_wrapper 2 %d\n", frame_number);
582 // No way to determine if there was an error based on nonzero status.
583 // Need to test row pointers to determine if an error occurred.
584 result
= avcodec_decode_video(codec
->decoder_context
[current_field
],
585 &codec
->picture
[current_field
],
589 //printf("decode_wrapper 3\n");
590 if(codec
->picture
[current_field
].data
[0])
592 if(!codec
->got_key
[current_field
])
594 codec
->got_key
[current_field
] = 1;
600 // ffmpeg can't recover if the first frame errored out, like in a direct copy
603 * delete_decoder(codec, current_field);
604 * init_decode(codec, current_field, width_i, height_i);
613 //printf("decode_wrapper 4\n");
618 static int decode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
622 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
623 quicktime_trak_t
*trak
= vtrack
->track
;
624 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
625 int width
= trak
->tkhd
.track_width
;
626 int height
= trak
->tkhd
.track_height
;
627 int width_i
= (int)((float)width
/ 16 + 0.5) * 16;
628 int height_i
= (int)((float)height
/ 16 + 0.5) * 16;
631 int current_field
= vtrack
->current_position
% codec
->total_fields
;
632 unsigned char **input_rows
;
633 int seeking_done
= 0;
636 pthread_mutex_lock(&ffmpeg_lock
);
639 if(!codec
->decode_initialized
[current_field
])
641 int current_frame
= vtrack
->current_position
;
642 init_decode(codec
, current_field
, width_i
, height_i
);
643 // Must decode frame with VOL header first but only the first frame in the
644 // field sequence has a VOL header.
645 result
= decode_wrapper(file
,
651 // Reset position because decode wrapper set it
652 quicktime_set_video_position(file
, current_frame
, track
);
653 codec
->decode_initialized
[current_field
] = 1;
655 //printf("decode 1 %d\n", vtrack->current_position);
658 if(quicktime_has_keyframes(file
, track
) &&
659 vtrack
->current_position
!= codec
->last_frame
[current_field
] + codec
->total_fields
)
661 int frame1
, frame2
= vtrack
->current_position
, current_frame
= frame2
;
663 //printf("decode 2\n");
665 // Get first keyframe of same field
668 frame1
= quicktime_get_keyframe_before(file
,
671 }while(frame1
> 0 && (frame1
% codec
->total_fields
) != current_field
);
672 //printf("decode 3\n");
674 // Keyframe is before last decoded frame and current frame is after last decoded
675 // frame, so instead of rerendering from the last keyframe we can rerender from
676 // the last decoded frame.
677 if(frame1
< codec
->last_frame
[current_field
] &&
678 frame2
> codec
->last_frame
[current_field
])
680 //printf("decode 1 %d %d\n", frame1, frame2);
681 frame1
= codec
->last_frame
[current_field
] + codec
->total_fields
;
684 //printf("decode 4\n");
686 while(frame1
<= frame2
)
688 result
= decode_wrapper(file
,
696 // May need to do the first I frame twice.
699 result
= decode_wrapper(file
,
707 frame1
+= codec
->total_fields
;
709 //printf("decode 5\n");
711 vtrack
->current_position
= frame2
;
714 //printf("decode 6\n");
718 result
= decode_wrapper(file
,
721 vtrack
->current_position
,
725 pthread_mutex_unlock(&ffmpeg_lock
);
726 //printf("decode 10\n");
729 codec
->last_frame
[current_field
] = vtrack
->current_position
;
739 // result = (result != 0);
740 switch(codec
->decoder_context
[current_field
]->pix_fmt
)
742 case PIX_FMT_YUV420P
:
743 input_cmodel
= BC_YUV420P
;
746 input_cmodel
= BC_YUV422
;
748 case PIX_FMT_YUV422P
:
749 input_cmodel
= BC_YUV422P
;
754 //printf("decode 20 %d %p\n", result, codec->picture[current_field].data[0]);
755 if(codec
->picture
[current_field
].data
[0])
757 int y_out_size
= codec
->decoder_context
[current_field
]->width
*
758 codec
->decoder_context
[current_field
]->height
;
759 int u_out_size
= codec
->decoder_context
[current_field
]->width
*
760 codec
->decoder_context
[current_field
]->height
/
762 int v_out_size
= codec
->decoder_context
[current_field
]->width
*
763 codec
->decoder_context
[current_field
]->height
/
765 int y_in_size
= codec
->picture
[current_field
].linesize
[0] *
766 codec
->decoder_context
[current_field
]->height
;
767 int u_in_size
= codec
->picture
[current_field
].linesize
[1] *
768 codec
->decoder_context
[current_field
]->height
/
770 int v_in_size
= codec
->picture
[current_field
].linesize
[2] *
771 codec
->decoder_context
[current_field
]->height
/
774 malloc(sizeof(unsigned char*) *
775 codec
->decoder_context
[current_field
]->height
);
777 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
++)
778 input_rows
[i
] = codec
->picture
[current_field
].data
[0] +
780 codec
->decoder_context
[current_field
]->width
*
781 cmodel_calculate_pixelsize(input_cmodel
);
783 if(!codec
->temp_frame
)
785 codec
->temp_frame
= malloc(y_out_size
+
790 if(codec
->picture
[current_field
].data
[0])
792 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
++)
794 memcpy(codec
->temp_frame
+ i
* codec
->decoder_context
[current_field
]->width
,
795 codec
->picture
[current_field
].data
[0] + i
* codec
->picture
[current_field
].linesize
[0],
796 codec
->decoder_context
[current_field
]->width
);
799 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
+= 2)
801 memcpy(codec
->temp_frame
+
804 codec
->decoder_context
[current_field
]->width
/ 2,
805 codec
->picture
[current_field
].data
[1] +
807 codec
->picture
[current_field
].linesize
[1],
808 codec
->decoder_context
[current_field
]->width
/ 2);
810 memcpy(codec
->temp_frame
+
814 codec
->decoder_context
[current_field
]->width
/ 2,
815 codec
->picture
[current_field
].data
[2] +
817 codec
->picture
[current_field
].linesize
[2],
818 codec
->decoder_context
[current_field
]->width
/ 2);
821 cmodel_transfer(row_pointers
, /* Leave NULL if non existent */
823 row_pointers
[0], /* Leave NULL if non existent */
826 codec
->temp_frame
, /* Leave NULL if non existent */
827 codec
->temp_frame
+ y_out_size
,
828 codec
->temp_frame
+ y_out_size
+ u_out_size
,
829 file
->in_x
, /* Dimensions to capture from input frame */
833 0, /* Dimensions to project on output frame */
839 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
840 codec
->decoder_context
[current_field
]->width
, /* For planar use the luma rowspan */
846 //printf("decode 100\n");
854 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
856 int64_t offset
= quicktime_position(file
);
857 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
858 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
859 quicktime_trak_t
*trak
= vtrack
->track
;
860 int width
= trak
->tkhd
.track_width
;
861 int height
= trak
->tkhd
.track_height
;
862 int width_i
= (int)((float)width
/ 16 + 0.5) * 16;
863 int height_i
= (int)((float)height
/ 16 + 0.5) * 16;
868 int current_field
= vtrack
->current_position
% codec
->total_fields
;
869 quicktime_atom_t chunk_atom
;
872 //printf("encode 1\n");
876 pthread_mutex_lock(&ffmpeg_lock
);
880 if(!codec
->encode_initialized
[current_field
])
883 if(codec
->ffmpeg_id
== CODEC_ID_MPEG4
)
885 codec
->use_encore
= 1;
886 codec
->encode_initialized
[current_field
] = 1;
887 codec
->encode_handle
[current_field
] = encode_handle
++;
888 codec
->enc_param
[current_field
].x_dim
= width_i
;
889 codec
->enc_param
[current_field
].y_dim
= height_i
;
890 codec
->enc_param
[current_field
].framerate
=
891 quicktime_frame_rate(file
, track
) / codec
->total_fields
;
892 codec
->enc_param
[current_field
].bitrate
=
893 codec
->bitrate
/ codec
->total_fields
;
894 codec
->enc_param
[current_field
].rc_period
= codec
->rc_period
;
895 codec
->enc_param
[current_field
].rc_reaction_period
= codec
->rc_reaction_period
;
896 codec
->enc_param
[current_field
].rc_reaction_ratio
= codec
->rc_reaction_ratio
;
897 codec
->enc_param
[current_field
].max_quantizer
= codec
->max_quantizer
;
898 codec
->enc_param
[current_field
].min_quantizer
= codec
->min_quantizer
;
899 codec
->enc_param
[current_field
].max_key_interval
= codec
->max_key_interval
;
901 codec
->enc_param
[current_field
].search_range
= codec
->quality
* 3;
902 if(codec
->enc_param
[current_field
].search_range
> 15)
903 codec
->enc_param
[current_field
].search_range
= 15;
905 encore(codec
->encode_handle
[current_field
],
907 &codec
->enc_param
[current_field
], NULL
);
913 static char *video_rc_eq
="tex^qComp";
914 codec
->encode_initialized
[current_field
] = 1;
915 if(!ffmpeg_initialized
)
917 ffmpeg_initialized
= 1;
919 avcodec_register_all();
922 codec
->encoder
[current_field
] = avcodec_find_encoder(codec
->ffmpeg_id
);
923 if(!codec
->encoder
[current_field
])
925 printf("encode: avcodec_find_encoder returned NULL.\n");
926 pthread_mutex_unlock(&ffmpeg_lock
);
930 codec
->encoder_context
[current_field
] = avcodec_alloc_context();
931 codec
->encoder_context
[current_field
]->frame_rate
= FRAME_RATE_BASE
*
932 quicktime_frame_rate(file
, track
);
933 codec
->encoder_context
[current_field
]->width
= width_i
;
934 codec
->encoder_context
[current_field
]->height
= height_i
;
935 codec
->encoder_context
[current_field
]->gop_size
= codec
->gop_size
;
936 codec
->encoder_context
[current_field
]->pix_fmt
= PIX_FMT_YUV420P
;
937 codec
->encoder_context
[current_field
]->bit_rate
= codec
->bitrate
;
938 codec
->encoder_context
[current_field
]->bit_rate_tolerance
= codec
->bitrate_tolerance
;
939 codec
->encoder_context
[current_field
]->rc_eq
= video_rc_eq
;
940 codec
->encoder_context
[current_field
]->qmin
= 2;
941 codec
->encoder_context
[current_field
]->qmax
= 31;
942 codec
->encoder_context
[current_field
]->max_qdiff
= 3;
943 codec
->encoder_context
[current_field
]->qblur
= 0.5;
944 codec
->encoder_context
[current_field
]->qcompress
= 0.5;
945 codec
->encoder_context
[current_field
]->me_method
= ME_FULL
;
947 printf("encode %d %d %d %d %d\n", codec
->gop_size
, codec
->bitrate
, codec
->bitrate_tolerance
, codec
->fix_bitrate
, codec
->interlaced
);
950 if(!codec
->fix_bitrate
)
952 codec
->encoder_context
[current_field
]->flags
|= CODEC_FLAG_QSCALE
;
955 if(codec
->interlaced
)
957 codec
->encoder_context
[current_field
]->flags
|= CODEC_FLAG_INTERLACED_DCT
;
960 avcodec_open(codec
->encoder_context
[current_field
], codec
->encoder
[current_field
]);
966 if(!codec
->work_buffer
)
968 codec
->buffer_size
= width_i
* height_i
;
969 codec
->work_buffer
= malloc(codec
->buffer_size
);
975 if(codec
->use_encore
)
978 ENC_FRAME encore_input
;
979 ENC_RESULT encore_result
;
982 // Assume planes are contiguous.
983 // Encode directly from function arguments
984 if(file
->color_model
== BC_YUV420P
&&
988 encore_input
.image
= row_pointers
[0];
990 // Convert to YUV420P
991 // Encode from temporary.
994 if(!codec
->temp_frame
)
996 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
999 cmodel_transfer(0, /* Leave NULL if non existent */
1001 codec
->temp_frame
, /* Leave NULL if non existent */
1002 codec
->temp_frame
+ width_i
* height_i
,
1003 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1004 row_pointers
[0], /* Leave NULL if non existent */
1007 0, /* Dimensions to capture from input frame */
1011 0, /* Dimensions to project on output frame */
1017 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1018 width
, /* For planar use the luma rowspan */
1022 encore_input
.image
= codec
->temp_frame
;
1027 bzero(codec
->work_buffer
, codec
->buffer_size
);
1028 encore_input
.bitstream
= codec
->work_buffer
;
1029 encore_input
.length
= 0;
1030 encore_input
.quant
= !codec
->fix_bitrate
? codec
->quantizer
: 0;
1032 if(codec
->p_count
== 0)
1034 codec
->p_count
[current_field
]++;
1038 codec
->p_count
[current_field
]++;
1039 if(codec
->p_count
[current_field
] >= codec
->max_key_interval
)
1040 codec
->p_count
[current_field
] = 0;
1043 encore(codec
->encode_handle
[current_field
],
1048 bytes
= encore_input
.length
;
1049 is_keyframe
= encore_result
.isKeyFrame
;
1056 if(width_i
== width
&&
1057 height_i
== height
&&
1058 file
->color_model
== BC_YUV420P
)
1060 pict_tmp
.data
[0] = row_pointers
[0];
1061 pict_tmp
.data
[1] = row_pointers
[1];
1062 pict_tmp
.data
[2] = row_pointers
[2];
1063 pict_tmp
.linesize
[0] = width_i
;
1064 pict_tmp
.linesize
[1] = width_i
/ 2;
1065 pict_tmp
.linesize
[2] = width_i
/ 2;
1069 if(!codec
->temp_frame
)
1071 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
1074 cmodel_transfer(0, /* Leave NULL if non existent */
1076 codec
->temp_frame
, /* Leave NULL if non existent */
1077 codec
->temp_frame
+ width_i
* height_i
,
1078 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1079 row_pointers
[0], /* Leave NULL if non existent */
1082 0, /* Dimensions to capture from input frame */
1086 0, /* Dimensions to project on output frame */
1092 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1093 width
, /* For planar use the luma rowspan */
1096 pict_tmp
.data
[0] = codec
->temp_frame
;
1097 pict_tmp
.data
[1] = codec
->temp_frame
+ width_i
* height_i
;
1098 pict_tmp
.data
[2] = codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4;
1099 pict_tmp
.linesize
[0] = width_i
;
1100 pict_tmp
.linesize
[1] = width_i
/ 2;
1101 pict_tmp
.linesize
[2] = width_i
/ 2;
1105 if(codec
->quantizer
>= 0)
1106 pict_tmp
.quality
= codec
->quantizer
;
1107 bytes
= avcodec_encode_video(codec
->encoder_context
[current_field
],
1111 is_keyframe
= pict_tmp
.key_frame
;
1119 pthread_mutex_unlock(&ffmpeg_lock
);
1120 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
1121 result
= !quicktime_write_data(file
,
1124 quicktime_write_chunk_footer(file
,
1126 vtrack
->current_chunk
,
1130 quicktime_insert_keyframe(file
,
1131 vtrack
->current_position
,
1133 //printf("encode 10\n");
1135 vtrack
->current_chunk
++;
1145 static int set_parameter(quicktime_t
*file
,
1150 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
1151 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
1153 if(quicktime_match_32(compressor
, QUICKTIME_DIVX
) ||
1154 quicktime_match_32(compressor
, QUICKTIME_HV60
))
1156 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1158 if(!strcasecmp(key
, "divx_bitrate"))
1159 codec
->bitrate
= *(int*)value
;
1161 if(!strcasecmp(key
, "divx_rc_period"))
1162 codec
->rc_period
= *(int*)value
;
1164 if(!strcasecmp(key
, "divx_rc_reaction_ratio"))
1165 codec
->rc_reaction_ratio
= *(int*)value
;
1167 if(!strcasecmp(key
, "divx_rc_reaction_period"))
1168 codec
->rc_reaction_period
= *(int*)value
;
1170 if(!strcasecmp(key
, "divx_max_key_interval"))
1171 codec
->max_key_interval
= *(int*)value
;
1173 if(!strcasecmp(key
, "divx_max_quantizer"))
1174 codec
->max_quantizer
= *(int*)value
;
1176 if(!strcasecmp(key
, "divx_min_quantizer"))
1177 codec
->min_quantizer
= *(int*)value
;
1179 if(!strcasecmp(key
, "divx_quantizer"))
1180 codec
->quantizer
= *(int*)value
;
1182 if(!strcasecmp(key
, "divx_quality"))
1183 codec
->quality
= *(int*)value
;
1185 if(!strcasecmp(key
, "divx_fix_bitrate"))
1186 codec
->fix_bitrate
= *(int*)value
;
1188 if(!strcasecmp(key
, "divx_use_deblocking"))
1189 codec
->use_deblocking
= *(int*)value
;
1192 if(quicktime_match_32(compressor
, QUICKTIME_DIV3
))
1194 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1195 if(!strcasecmp(key
, "div3_bitrate"))
1196 codec
->bitrate
= *(int*)value
;
1198 if(!strcasecmp(key
, "div3_bitrate_tolerance"))
1199 codec
->bitrate_tolerance
= *(int*)value
;
1201 if(!strcasecmp(key
, "div3_interlaced"))
1202 codec
->interlaced
= *(int*)value
;
1204 if(!strcasecmp(key
, "div3_gop_size"))
1205 codec
->gop_size
= *(int*)value
;
1207 if(!strcasecmp(key
, "div3_quantizer"))
1208 codec
->quantizer
= *(int*)value
;
1210 if(!strcasecmp(key
, "div3_fix_bitrate"))
1211 codec
->fix_bitrate
= *(int*)value
;
1218 static int delete_codec(quicktime_video_map_t
*vtrack
)
1220 quicktime_mpeg4_codec_t
*codec
;
1224 codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1225 for(i
= 0; i
< codec
->total_fields
; i
++)
1227 if(codec
->encode_initialized
[i
])
1229 pthread_mutex_lock(&ffmpeg_lock
);
1230 if(codec
->use_encore
)
1232 encore(codec
->encode_handle
[i
],
1239 avcodec_close(codec
->encoder_context
[i
]);
1240 free(codec
->encoder_context
[i
]);
1242 pthread_mutex_unlock(&ffmpeg_lock
);
1244 delete_decoder(codec
, i
);
1248 if(codec
->temp_frame
) free(codec
->temp_frame
);
1249 if(codec
->work_buffer
) free(codec
->work_buffer
);
1259 static quicktime_mpeg4_codec_t
* init_common(quicktime_video_map_t
*vtrack
,
1264 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
1265 quicktime_mpeg4_codec_t
*codec
;
1267 codec_base
->priv
= calloc(1, sizeof(quicktime_mpeg4_codec_t
));
1268 codec_base
->delete_vcodec
= delete_codec
;
1269 codec_base
->decode_video
= decode
;
1270 codec_base
->encode_video
= encode
;
1271 codec_base
->reads_colormodel
= reads_colormodel
;
1272 codec_base
->writes_colormodel
= writes_colormodel
;
1273 codec_base
->set_parameter
= set_parameter
;
1274 codec_base
->fourcc
= compressor
;
1275 codec_base
->title
= title
;
1276 codec_base
->desc
= description
;
1278 codec
= (quicktime_mpeg4_codec_t
*)codec_base
->priv
;
1283 codec
->bitrate
= 1000000;
1284 codec
->rc_period
= 50;
1285 codec
->rc_reaction_ratio
= 45;
1286 codec
->rc_reaction_period
= 10;
1287 codec
->max_key_interval
= 45;
1288 codec
->max_quantizer
= 31;
1289 codec
->min_quantizer
= 1;
1290 codec
->quantizer
= 10;
1292 codec
->fix_bitrate
= 1;
1293 codec
->total_fields
= 1;
1303 // Mike Rowe Soft MPEG-4
1304 void quicktime_init_codec_div3(quicktime_video_map_t
*vtrack
)
1306 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1309 "Mike Row Soft MPEG4 Version 3");
1310 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1313 // Mike Rowe Soft MPEG-4
1314 void quicktime_init_codec_div3lower(quicktime_video_map_t
*vtrack
)
1316 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1317 QUICKTIME_DIV3_LOWER
,
1319 "Mike Row Soft MPEG4 Version 3");
1320 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1325 void quicktime_init_codec_divx(quicktime_video_map_t
*vtrack
)
1327 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1330 "Generic MPEG Four");
1331 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1336 void quicktime_init_codec_svq1(quicktime_video_map_t
*vtrack
)
1338 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1340 "Sorenson Version 1",
1341 "From the chearch of codecs of yesterday's sights");
1342 result
->ffmpeg_id
= CODEC_ID_SVQ1
;
1345 // field based MPEG-4
1346 void quicktime_init_codec_hv60(quicktime_video_map_t
*vtrack
)
1348 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1351 "MPEG 4 with alternating streams every other frame. (Not standardized)");
1352 result
->total_fields
= 2;
1353 result
->ffmpeg_id
= CODEC_ID_MPEG4
;