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
&= 0xffffffffffffffff >> (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 init_decode(codec
, current_field
, width_i
, height_i
);
642 // Must decode frame with VOL header first but only the first frame in the
643 // field sequence has a VOL header.
644 result
= decode_wrapper(file
,
650 codec
->decode_initialized
[current_field
] = 1;
652 //printf("decode 1\n");
655 if(quicktime_has_keyframes(file
, track
) &&
656 vtrack
->current_position
!= codec
->last_frame
[current_field
] + codec
->total_fields
)
658 int frame1
, frame2
= vtrack
->current_position
, current_frame
= frame2
;
660 //printf("decode 2\n");
662 // Get first keyframe of same field
665 frame1
= quicktime_get_keyframe_before(file
,
668 }while(frame1
> 0 && (frame1
% codec
->total_fields
) != current_field
);
669 //printf("decode 3\n");
671 // Keyframe is before last decoded frame and current frame is after last decoded
672 // frame, so instead of rerendering from the last keyframe we can rerender from
673 // the last decoded frame.
674 if(frame1
< codec
->last_frame
[current_field
] &&
675 frame2
> codec
->last_frame
[current_field
])
677 //printf("decode 1 %d %d\n", frame1, frame2);
678 frame1
= codec
->last_frame
[current_field
] + codec
->total_fields
;
681 //printf("decode 4\n");
683 while(frame1
<= frame2
)
685 result
= decode_wrapper(file
,
693 // May need to do the first I frame twice.
696 result
= decode_wrapper(file
,
704 frame1
+= codec
->total_fields
;
706 //printf("decode 5\n");
708 vtrack
->current_position
= frame2
;
711 //printf("decode 6\n");
715 result
= decode_wrapper(file
,
718 vtrack
->current_position
,
722 pthread_mutex_unlock(&ffmpeg_lock
);
723 //printf("decode 10\n");
726 codec
->last_frame
[current_field
] = vtrack
->current_position
;
736 // result = (result != 0);
737 switch(codec
->decoder_context
[current_field
]->pix_fmt
)
739 case PIX_FMT_YUV420P
:
740 input_cmodel
= BC_YUV420P
;
743 input_cmodel
= BC_YUV422
;
745 case PIX_FMT_YUV422P
:
746 input_cmodel
= BC_YUV422P
;
751 //printf("decode 20 %d %p\n", result, codec->picture[current_field].data[0]);
752 if(codec
->picture
[current_field
].data
[0])
754 int y_out_size
= codec
->decoder_context
[current_field
]->width
*
755 codec
->decoder_context
[current_field
]->height
;
756 int u_out_size
= codec
->decoder_context
[current_field
]->width
*
757 codec
->decoder_context
[current_field
]->height
/
759 int v_out_size
= codec
->decoder_context
[current_field
]->width
*
760 codec
->decoder_context
[current_field
]->height
/
762 int y_in_size
= codec
->picture
[current_field
].linesize
[0] *
763 codec
->decoder_context
[current_field
]->height
;
764 int u_in_size
= codec
->picture
[current_field
].linesize
[1] *
765 codec
->decoder_context
[current_field
]->height
/
767 int v_in_size
= codec
->picture
[current_field
].linesize
[2] *
768 codec
->decoder_context
[current_field
]->height
/
771 malloc(sizeof(unsigned char*) *
772 codec
->decoder_context
[current_field
]->height
);
774 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
++)
775 input_rows
[i
] = codec
->picture
[current_field
].data
[0] +
777 codec
->decoder_context
[current_field
]->width
*
778 cmodel_calculate_pixelsize(input_cmodel
);
780 if(!codec
->temp_frame
)
782 codec
->temp_frame
= malloc(y_out_size
+
787 if(codec
->picture
[current_field
].data
[0])
789 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
++)
791 memcpy(codec
->temp_frame
+ i
* codec
->decoder_context
[current_field
]->width
,
792 codec
->picture
[current_field
].data
[0] + i
* codec
->picture
[current_field
].linesize
[0],
793 codec
->decoder_context
[current_field
]->width
);
796 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
+= 2)
798 memcpy(codec
->temp_frame
+
801 codec
->decoder_context
[current_field
]->width
/ 2,
802 codec
->picture
[current_field
].data
[1] +
804 codec
->picture
[current_field
].linesize
[1],
805 codec
->decoder_context
[current_field
]->width
/ 2);
807 memcpy(codec
->temp_frame
+
811 codec
->decoder_context
[current_field
]->width
/ 2,
812 codec
->picture
[current_field
].data
[2] +
814 codec
->picture
[current_field
].linesize
[2],
815 codec
->decoder_context
[current_field
]->width
/ 2);
818 cmodel_transfer(row_pointers
, /* Leave NULL if non existent */
820 row_pointers
[0], /* Leave NULL if non existent */
823 codec
->temp_frame
, /* Leave NULL if non existent */
824 codec
->temp_frame
+ y_out_size
,
825 codec
->temp_frame
+ y_out_size
+ u_out_size
,
826 file
->in_x
, /* Dimensions to capture from input frame */
830 0, /* Dimensions to project on output frame */
836 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
837 codec
->decoder_context
[current_field
]->width
, /* For planar use the luma rowspan */
843 //printf("decode 100\n");
851 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
853 int64_t offset
= quicktime_position(file
);
854 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
855 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
856 quicktime_trak_t
*trak
= vtrack
->track
;
857 int width
= trak
->tkhd
.track_width
;
858 int height
= trak
->tkhd
.track_height
;
859 int width_i
= (int)((float)width
/ 16 + 0.5) * 16;
860 int height_i
= (int)((float)height
/ 16 + 0.5) * 16;
865 int current_field
= vtrack
->current_position
% codec
->total_fields
;
866 quicktime_atom_t chunk_atom
;
869 //printf("encode 1\n");
873 pthread_mutex_lock(&ffmpeg_lock
);
877 if(!codec
->encode_initialized
[current_field
])
880 if(codec
->ffmpeg_id
== CODEC_ID_MPEG4
)
882 codec
->use_encore
= 1;
883 codec
->encode_initialized
[current_field
] = 1;
884 codec
->encode_handle
[current_field
] = encode_handle
++;
885 codec
->enc_param
[current_field
].x_dim
= width_i
;
886 codec
->enc_param
[current_field
].y_dim
= height_i
;
887 codec
->enc_param
[current_field
].framerate
=
888 quicktime_frame_rate(file
, track
) / codec
->total_fields
;
889 codec
->enc_param
[current_field
].bitrate
=
890 codec
->bitrate
/ codec
->total_fields
;
891 codec
->enc_param
[current_field
].rc_period
= codec
->rc_period
;
892 codec
->enc_param
[current_field
].rc_reaction_period
= codec
->rc_reaction_period
;
893 codec
->enc_param
[current_field
].rc_reaction_ratio
= codec
->rc_reaction_ratio
;
894 codec
->enc_param
[current_field
].max_quantizer
= codec
->max_quantizer
;
895 codec
->enc_param
[current_field
].min_quantizer
= codec
->min_quantizer
;
896 codec
->enc_param
[current_field
].max_key_interval
= codec
->max_key_interval
;
898 codec
->enc_param
[current_field
].search_range
= codec
->quality
* 3;
899 if(codec
->enc_param
[current_field
].search_range
> 15)
900 codec
->enc_param
[current_field
].search_range
= 15;
902 encore(codec
->encode_handle
[current_field
],
904 &codec
->enc_param
[current_field
], NULL
);
910 static char *video_rc_eq
="tex^qComp";
911 codec
->encode_initialized
[current_field
] = 1;
912 if(!ffmpeg_initialized
)
914 ffmpeg_initialized
= 1;
916 avcodec_register_all();
919 codec
->encoder
[current_field
] = avcodec_find_encoder(codec
->ffmpeg_id
);
920 if(!codec
->encoder
[current_field
])
922 printf("encode: avcodec_find_encoder returned NULL.\n");
923 pthread_mutex_unlock(&ffmpeg_lock
);
927 codec
->encoder_context
[current_field
] = avcodec_alloc_context();
928 codec
->encoder_context
[current_field
]->frame_rate
= FRAME_RATE_BASE
*
929 quicktime_frame_rate(file
, track
);
930 codec
->encoder_context
[current_field
]->width
= width_i
;
931 codec
->encoder_context
[current_field
]->height
= height_i
;
932 codec
->encoder_context
[current_field
]->gop_size
= codec
->gop_size
;
933 codec
->encoder_context
[current_field
]->pix_fmt
= PIX_FMT_YUV420P
;
934 codec
->encoder_context
[current_field
]->bit_rate
= codec
->bitrate
;
935 codec
->encoder_context
[current_field
]->bit_rate_tolerance
= codec
->bitrate_tolerance
;
936 codec
->encoder_context
[current_field
]->rc_eq
= video_rc_eq
;
937 codec
->encoder_context
[current_field
]->qmin
= 2;
938 codec
->encoder_context
[current_field
]->qmax
= 31;
939 codec
->encoder_context
[current_field
]->max_qdiff
= 3;
940 codec
->encoder_context
[current_field
]->qblur
= 0.5;
941 codec
->encoder_context
[current_field
]->qcompress
= 0.5;
942 codec
->encoder_context
[current_field
]->me_method
= ME_FULL
;
944 printf("encode %d %d %d %d %d\n", codec
->gop_size
, codec
->bitrate
, codec
->bitrate_tolerance
, codec
->fix_bitrate
, codec
->interlaced
);
947 if(!codec
->fix_bitrate
)
949 codec
->encoder_context
[current_field
]->flags
|= CODEC_FLAG_QSCALE
;
952 if(codec
->interlaced
)
954 codec
->encoder_context
[current_field
]->flags
|= CODEC_FLAG_INTERLACED_DCT
;
957 avcodec_open(codec
->encoder_context
[current_field
], codec
->encoder
[current_field
]);
963 if(!codec
->work_buffer
)
965 codec
->buffer_size
= width_i
* height_i
;
966 codec
->work_buffer
= malloc(codec
->buffer_size
);
972 if(codec
->use_encore
)
975 ENC_FRAME encore_input
;
976 ENC_RESULT encore_result
;
979 // Assume planes are contiguous.
980 // Encode directly from function arguments
981 if(file
->color_model
== BC_YUV420P
&&
985 encore_input
.image
= row_pointers
[0];
987 // Convert to YUV420P
988 // Encode from temporary.
991 if(!codec
->temp_frame
)
993 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
996 cmodel_transfer(0, /* Leave NULL if non existent */
998 codec
->temp_frame
, /* Leave NULL if non existent */
999 codec
->temp_frame
+ width_i
* height_i
,
1000 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1001 row_pointers
[0], /* Leave NULL if non existent */
1004 0, /* Dimensions to capture from input frame */
1008 0, /* Dimensions to project on output frame */
1014 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1015 width
, /* For planar use the luma rowspan */
1019 encore_input
.image
= codec
->temp_frame
;
1024 bzero(codec
->work_buffer
, codec
->buffer_size
);
1025 encore_input
.bitstream
= codec
->work_buffer
;
1026 encore_input
.length
= 0;
1027 encore_input
.quant
= !codec
->fix_bitrate
? codec
->quantizer
: 0;
1029 if(codec
->p_count
== 0)
1031 codec
->p_count
[current_field
]++;
1035 codec
->p_count
[current_field
]++;
1036 if(codec
->p_count
[current_field
] >= codec
->max_key_interval
)
1037 codec
->p_count
[current_field
] = 0;
1040 encore(codec
->encode_handle
[current_field
],
1045 bytes
= encore_input
.length
;
1046 is_keyframe
= encore_result
.isKeyFrame
;
1053 if(width_i
== width
&&
1054 height_i
== height
&&
1055 file
->color_model
== BC_YUV420P
)
1057 pict_tmp
.data
[0] = row_pointers
[0];
1058 pict_tmp
.data
[1] = row_pointers
[1];
1059 pict_tmp
.data
[2] = row_pointers
[2];
1060 pict_tmp
.linesize
[0] = width_i
;
1061 pict_tmp
.linesize
[1] = width_i
/ 2;
1062 pict_tmp
.linesize
[2] = width_i
/ 2;
1066 if(!codec
->temp_frame
)
1068 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
1071 cmodel_transfer(0, /* Leave NULL if non existent */
1073 codec
->temp_frame
, /* Leave NULL if non existent */
1074 codec
->temp_frame
+ width_i
* height_i
,
1075 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1076 row_pointers
[0], /* Leave NULL if non existent */
1079 0, /* Dimensions to capture from input frame */
1083 0, /* Dimensions to project on output frame */
1089 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1090 width
, /* For planar use the luma rowspan */
1093 pict_tmp
.data
[0] = codec
->temp_frame
;
1094 pict_tmp
.data
[1] = codec
->temp_frame
+ width_i
* height_i
;
1095 pict_tmp
.data
[2] = codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4;
1096 pict_tmp
.linesize
[0] = width_i
;
1097 pict_tmp
.linesize
[1] = width_i
/ 2;
1098 pict_tmp
.linesize
[2] = width_i
/ 2;
1102 if(codec
->quantizer
>= 0)
1103 pict_tmp
.quality
= codec
->quantizer
;
1104 bytes
= avcodec_encode_video(codec
->encoder_context
[current_field
],
1108 is_keyframe
= pict_tmp
.key_frame
;
1116 pthread_mutex_unlock(&ffmpeg_lock
);
1117 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
1118 result
= !quicktime_write_data(file
,
1121 quicktime_write_chunk_footer(file
,
1123 vtrack
->current_chunk
,
1127 quicktime_insert_keyframe(file
,
1128 vtrack
->current_position
,
1130 //printf("encode 10\n");
1132 vtrack
->current_chunk
++;
1142 static int set_parameter(quicktime_t
*file
,
1147 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
1148 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
1150 if(quicktime_match_32(compressor
, QUICKTIME_DIVX
) ||
1151 quicktime_match_32(compressor
, QUICKTIME_HV60
))
1153 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1155 if(!strcasecmp(key
, "divx_bitrate"))
1156 codec
->bitrate
= *(int*)value
;
1158 if(!strcasecmp(key
, "divx_rc_period"))
1159 codec
->rc_period
= *(int*)value
;
1161 if(!strcasecmp(key
, "divx_rc_reaction_ratio"))
1162 codec
->rc_reaction_ratio
= *(int*)value
;
1164 if(!strcasecmp(key
, "divx_rc_reaction_period"))
1165 codec
->rc_reaction_period
= *(int*)value
;
1167 if(!strcasecmp(key
, "divx_max_key_interval"))
1168 codec
->max_key_interval
= *(int*)value
;
1170 if(!strcasecmp(key
, "divx_max_quantizer"))
1171 codec
->max_quantizer
= *(int*)value
;
1173 if(!strcasecmp(key
, "divx_min_quantizer"))
1174 codec
->min_quantizer
= *(int*)value
;
1176 if(!strcasecmp(key
, "divx_quantizer"))
1177 codec
->quantizer
= *(int*)value
;
1179 if(!strcasecmp(key
, "divx_quality"))
1180 codec
->quality
= *(int*)value
;
1182 if(!strcasecmp(key
, "divx_fix_bitrate"))
1183 codec
->fix_bitrate
= *(int*)value
;
1185 if(!strcasecmp(key
, "divx_use_deblocking"))
1186 codec
->use_deblocking
= *(int*)value
;
1189 if(quicktime_match_32(compressor
, QUICKTIME_DIV3
))
1191 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1192 if(!strcasecmp(key
, "div3_bitrate"))
1193 codec
->bitrate
= *(int*)value
;
1195 if(!strcasecmp(key
, "div3_bitrate_tolerance"))
1196 codec
->bitrate_tolerance
= *(int*)value
;
1198 if(!strcasecmp(key
, "div3_interlaced"))
1199 codec
->interlaced
= *(int*)value
;
1201 if(!strcasecmp(key
, "div3_gop_size"))
1202 codec
->gop_size
= *(int*)value
;
1204 if(!strcasecmp(key
, "div3_quantizer"))
1205 codec
->quantizer
= *(int*)value
;
1207 if(!strcasecmp(key
, "div3_fix_bitrate"))
1208 codec
->fix_bitrate
= *(int*)value
;
1215 static int delete_codec(quicktime_video_map_t
*vtrack
)
1217 quicktime_mpeg4_codec_t
*codec
;
1221 codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1222 for(i
= 0; i
< codec
->total_fields
; i
++)
1224 if(codec
->encode_initialized
[i
])
1226 pthread_mutex_lock(&ffmpeg_lock
);
1227 if(codec
->use_encore
)
1229 encore(codec
->encode_handle
[i
],
1236 avcodec_close(codec
->encoder_context
[i
]);
1237 free(codec
->encoder_context
[i
]);
1239 pthread_mutex_unlock(&ffmpeg_lock
);
1241 delete_decoder(codec
, i
);
1245 if(codec
->temp_frame
) free(codec
->temp_frame
);
1246 if(codec
->work_buffer
) free(codec
->work_buffer
);
1256 static quicktime_mpeg4_codec_t
* init_common(quicktime_video_map_t
*vtrack
,
1261 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
1262 quicktime_mpeg4_codec_t
*codec
;
1264 codec_base
->priv
= calloc(1, sizeof(quicktime_mpeg4_codec_t
));
1265 codec_base
->delete_vcodec
= delete_codec
;
1266 codec_base
->decode_video
= decode
;
1267 codec_base
->encode_video
= encode
;
1268 codec_base
->reads_colormodel
= reads_colormodel
;
1269 codec_base
->writes_colormodel
= writes_colormodel
;
1270 codec_base
->set_parameter
= set_parameter
;
1271 codec_base
->fourcc
= compressor
;
1272 codec_base
->title
= title
;
1273 codec_base
->desc
= description
;
1275 codec
= (quicktime_mpeg4_codec_t
*)codec_base
->priv
;
1280 codec
->bitrate
= 1000000;
1281 codec
->rc_period
= 50;
1282 codec
->rc_reaction_ratio
= 45;
1283 codec
->rc_reaction_period
= 10;
1284 codec
->max_key_interval
= 45;
1285 codec
->max_quantizer
= 31;
1286 codec
->min_quantizer
= 1;
1287 codec
->quantizer
= 10;
1289 codec
->fix_bitrate
= 1;
1290 codec
->total_fields
= 1;
1300 // Mike Rowe Soft MPEG-4
1301 void quicktime_init_codec_div3(quicktime_video_map_t
*vtrack
)
1303 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1306 "Mike Row Soft MPEG4 Version 3");
1307 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1310 // Mike Rowe Soft MPEG-4
1311 void quicktime_init_codec_div3lower(quicktime_video_map_t
*vtrack
)
1313 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1314 QUICKTIME_DIV3_LOWER
,
1316 "Mike Row Soft MPEG4 Version 3");
1317 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1322 void quicktime_init_codec_divx(quicktime_video_map_t
*vtrack
)
1324 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1327 "Generic MPEG Four");
1328 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1333 void quicktime_init_codec_svq1(quicktime_video_map_t
*vtrack
)
1335 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1337 "Sorenson Version 1",
1338 "From the chearch of codecs of yesterday's sights");
1339 result
->ffmpeg_id
= CODEC_ID_SVQ1
;
1342 // field based MPEG-4
1343 void quicktime_init_codec_hv60(quicktime_video_map_t
*vtrack
)
1345 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1348 "MPEG 4 with alternating streams every other frame. (Not standardized)");
1349 result
->total_fields
= 2;
1350 result
->ffmpeg_id
= CODEC_ID_MPEG4
;