GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS
- ("video/x-h264, stream-format=(string)\"avc\", alignment=(string)\"au\", profile=(string)\"baseline\"")
+ ("video/x-h264, stream-format=(string)\"byte-stream\", alignment=(string)\"au\", profile=(string)\"baseline\"")
);
/* class initialization */
break;
case PROP_COMPLEXITY:
- openh264enc->complexity =
- (ECOMPLEXITY_MODE) g_value_get_enum (value);
+ openh264enc->complexity = (ECOMPLEXITY_MODE) g_value_get_enum (value);
break;
default:
{
GstOpenh264Enc *openh264enc = GST_OPENH264ENC (encoder);
gchar *debug_caps;
- SFrameBSInfo bsInfo;
guint width, height, fps_n, fps_d;
SEncParamExt enc_params;
gint ret;
- guchar *nal_sps_data = NULL;
- gint nal_sps_length = 0;
- guchar *nal_pps_data = NULL;
- gint nal_pps_length = 0;
- guchar *sps_tmp_buf;
- guchar *codec_data_tmp_buf;
- GstBuffer *codec_data;
GstCaps *outcaps;
GstVideoCodecState *output_state;
openh264enc->frame_count = 0;
enc_params.bEnableDenoise = openh264enc->enable_denoise;
enc_params.iComplexityMode = openh264enc->complexity;
enc_params.uiIntraPeriod = openh264enc->gop_size;
- enc_params.bEnableBackgroundDetection =
- openh264enc->background_detection;
+ enc_params.bEnableBackgroundDetection = openh264enc->background_detection;
enc_params.bEnableAdaptiveQuant = openh264enc->adaptive_quantization;
- enc_params.bEnableSceneChangeDetect =
- openh264enc->scene_change_detection;
+ enc_params.bEnableSceneChangeDetect = openh264enc->scene_change_detection;
enc_params.bEnableFrameSkip = openh264enc->enable_frame_skip;
enc_params.bEnableLongTermReference = 0;
#if OPENH264_MINOR >= 4
enc_params.sSpatialLayers[0].iVideoHeight = height;
enc_params.sSpatialLayers[0].fFrameRate = fps_n * 1.0 / fps_d;
enc_params.sSpatialLayers[0].iSpatialBitrate = openh264enc->bitrate;
- enc_params.sSpatialLayers[0].sSliceCfg.uiSliceMode =
- openh264enc->slice_mode;
+ enc_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = openh264enc->slice_mode;
enc_params.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum =
openh264enc->num_slices;
openh264enc->encoder->SetOption (ENCODER_OPTION_DATAFORMAT, &video_format);
- memset (&bsInfo, 0, sizeof (SFrameBSInfo));
-
- ret = openh264enc->encoder->EncodeParameterSets (&bsInfo);
-
- nal_sps_data = bsInfo.sLayerInfo[0].pBsBuf + 4;
- nal_sps_length = bsInfo.sLayerInfo[0].pNalLengthInByte[0] - 4;
-
- nal_pps_data = bsInfo.sLayerInfo[0].pBsBuf + nal_sps_length + 8;
- nal_pps_length = bsInfo.sLayerInfo[0].pNalLengthInByte[1] - 4;
-
- if (ret != cmResultSuccess) {
- GST_ELEMENT_ERROR (openh264enc, STREAM, ENCODE,
- ("Could not create headers"), ("Could not create SPS"));
- return FALSE;
- }
-
- sps_tmp_buf = (guchar *) (g_memdup (nal_sps_data, nal_sps_length));
-
- codec_data_tmp_buf =
- (guchar *) g_malloc (5 + 3 + nal_sps_length + 3 + nal_pps_length);
- codec_data_tmp_buf[0] = 1; /* version 1 */ ;
- codec_data_tmp_buf[1] = sps_tmp_buf[1]; /* profile */
- codec_data_tmp_buf[2] = sps_tmp_buf[2]; /* profile constraints */
- codec_data_tmp_buf[3] = sps_tmp_buf[3]; /* level */
- codec_data_tmp_buf[4] = 1; /* NAL length marker length minus one */
- codec_data_tmp_buf[5] = 1; /* Number of SPS */
- GST_WRITE_UINT16_BE (codec_data_tmp_buf + 6, nal_sps_length);
- memcpy (codec_data_tmp_buf + 8, sps_tmp_buf, nal_sps_length);
-
- g_free (sps_tmp_buf);
-
- codec_data_tmp_buf[8 + nal_sps_length] = 1; /* Number of PPS */
- GST_WRITE_UINT16_BE (codec_data_tmp_buf + 8 + nal_sps_length + 1,
- nal_pps_length);
- memcpy (codec_data_tmp_buf + 8 + nal_sps_length + 3, nal_pps_data,
- nal_pps_length);
-
- GST_DEBUG_OBJECT (openh264enc, "Got SPS of size %d and PPS of size %d",
- nal_sps_length, nal_pps_length);
-
- codec_data =
- gst_buffer_new_wrapped (codec_data_tmp_buf,
- 5 + 3 + nal_sps_length + 3 + nal_pps_length);
-
outcaps =
gst_caps_copy (gst_static_pad_template_get_caps
(&gst_openh264enc_src_template));
- gst_caps_set_simple (outcaps, "codec_data", GST_TYPE_BUFFER, codec_data,
- NULL);
- gst_buffer_unref (codec_data);
output_state = gst_video_encoder_set_output_state (encoder, outcaps, state);
gst_video_codec_state_unref (output_state);
gint ret;
SFrameBSInfo frame_info;
gfloat fps;
- GstVideoEncoder *base_encoder = GST_VIDEO_ENCODER (openh264enc);
+ GstMapInfo map;
+ gint i, j;
+ gsize buf_length = 0;
if (frame) {
src_pic = new SSourcePicture;
openh264enc->frame_count++;
if (frame) {
if (G_UNLIKELY (openh264enc->frame_count == 1)) {
- openh264enc->time_per_frame =
- (GST_NSECOND / openh264enc->framerate);
+ openh264enc->time_per_frame = (GST_NSECOND / openh264enc->framerate);
openh264enc->previous_timestamp = frame->pts;
} else {
openh264enc->time_per_frame =
if (videoFrameTypeSkip == frame_info.eFrameType) {
if (frame) {
gst_video_frame_unmap (&video_frame);
- gst_video_encoder_finish_frame (base_encoder, frame);
+ gst_video_encoder_finish_frame (encoder, frame);
delete src_pic;
}
/* FIXME: openh264 has no way for us to get a connection
* between the input and output frames, we just have to
* guess based on the input */
- frame = gst_video_encoder_get_oldest_frame (base_encoder);
+ frame = gst_video_encoder_get_oldest_frame (encoder);
if (!frame) {
GST_ELEMENT_ERROR (openh264enc, STREAM, ENCODE,
("Could not encode frame"), ("openh264enc returned %d", ret));
return GST_FLOW_ERROR;
}
- SLayerBSInfo *bs_info = &frame_info.sLayerInfo[0];
- gint nal_size = bs_info->pNalLengthInByte[0] - 4;
- guchar *nal_sps_data, *nal_pps_data;
- gint nal_sps_length, nal_pps_length, idr_length, tmp_buf_length;
-
if (videoFrameTypeIDR == frame_info.eFrameType) {
- GstMapInfo map;
-
- /* sps */
- nal_sps_data = frame_info.sLayerInfo[0].pBsBuf + 4;
- nal_sps_length = frame_info.sLayerInfo[0].pNalLengthInByte[0] - 4;
- /* pps */
- nal_pps_data = nal_sps_data + frame_info.sLayerInfo[0].pNalLengthInByte[0];
- nal_pps_length = frame_info.sLayerInfo[0].pNalLengthInByte[1] - 4;
- /* idr */
- bs_info = &frame_info.sLayerInfo[1];
- idr_length = bs_info->pNalLengthInByte[0] - 4;
-
- tmp_buf_length = nal_sps_length + 2 + nal_pps_length + 2 + idr_length + 2;
- frame->output_buffer =
- gst_video_encoder_allocate_output_buffer (encoder, tmp_buf_length);
- gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
-
- GST_WRITE_UINT16_BE (map.data, nal_sps_length);
- memcpy (map.data + 2, nal_sps_data, nal_sps_length);
-
- GST_WRITE_UINT16_BE (map.data + nal_sps_length + 2, nal_pps_length);
- memcpy (map.data + nal_sps_length + 2 + 2, nal_pps_data, nal_pps_length);
-
- GST_WRITE_UINT16_BE (map.data + nal_sps_length + 2 + nal_pps_length + 2,
- idr_length);
- memcpy (map.data + nal_sps_length + 2 + nal_pps_length + 2 + 2,
- bs_info->pBsBuf + 4, idr_length);
-
- gst_buffer_unmap (frame->output_buffer, &map);
-
GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
} else {
- GstMapInfo map;
-
- tmp_buf_length = nal_size + 2;
- frame->output_buffer =
- gst_video_encoder_allocate_output_buffer (encoder, tmp_buf_length);
- gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
+ GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
+ }
- GST_WRITE_UINT16_BE (map.data, nal_size);
- memcpy (map.data + 2, bs_info->pBsBuf + 4, nal_size);
+ for (i = 0; i < frame_info.iLayerNum; i++) {
+ for (j = 0; j < frame_info.sLayerInfo[i].iNalCount; j++) {
+ buf_length += frame_info.sLayerInfo[i].pNalLengthInByte[j];
+ }
+ }
- gst_buffer_unmap (frame->output_buffer, &map);
+ frame->output_buffer =
+ gst_video_encoder_allocate_output_buffer (encoder, buf_length);
+ gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
- GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
+ buf_length = 0;
+ for (i = 0; i < frame_info.iLayerNum; i++) {
+ gsize layer_size = 0;
+ for (j = 0; j < frame_info.sLayerInfo[i].iNalCount; j++) {
+ layer_size += frame_info.sLayerInfo[i].pNalLengthInByte[j];
+ }
+ memcpy (map.data + buf_length, frame_info.sLayerInfo[i].pBsBuf, layer_size);
+ buf_length += layer_size;
}
+ gst_buffer_unmap (frame->output_buffer, &map);
+
GST_LOG_OBJECT (openh264enc, "openh264 picture %scoded OK!",
(ret != cmResultSuccess) ? "NOT " : "");