static GstVaapiEncoderStatus gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); GstVaapiEncPicture *picture = NULL; GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; if (!frame) { if (g_queue_is_empty (&encoder->b_frames) && encoder->dump_frames) { push_reference (encoder, NULL); encoder->dump_frames = FALSE; } if (!encoder->dump_frames) { return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } picture = g_queue_pop_head (&encoder->b_frames); g_assert (picture); goto end; } picture = GST_VAAPI_ENC_PICTURE_NEW (MPEG2, encoder, frame); if (!picture) { GST_WARNING ("create MPEG2 picture failed, frame timestamp:%" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } if (encoder->frame_num >= base_encoder->keyframe_period) { encoder->frame_num = 0; clear_references (encoder); } if (encoder->frame_num == 0) { picture->type = GST_VAAPI_PICTURE_TYPE_I; GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame); encoder->new_gop = TRUE; } else { encoder->new_gop = FALSE; if ((encoder->frame_num % (encoder->ip_period + 1)) == 0 || encoder->frame_num == base_encoder->keyframe_period - 1) { picture->type = GST_VAAPI_PICTURE_TYPE_P; encoder->dump_frames = TRUE; } else { picture->type = GST_VAAPI_PICTURE_TYPE_B; status = GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } } picture->frame_num = encoder->frame_num++; if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { g_queue_push_tail (&encoder->b_frames, picture); picture = NULL; } end: *output = picture; return status; }
static GstVaapiEncoderStatus gst_vaapi_encoder_mpeg2_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; reconstruct = gst_vaapi_encoder_create_surface (base_encoder); g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); if (!ensure_sequence (encoder, picture)) goto error; if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) goto error; if (!set_misc_parameters (encoder, picture)) goto error; if (!ensure_slices (encoder, picture)) goto error; if (!gst_vaapi_enc_picture_encode (picture)) goto error; if (picture->type != GST_VAAPI_PICTURE_TYPE_B) { if (encoder->new_gop) clear_references (encoder); push_reference (encoder, reconstruct); } else if (reconstruct) gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), reconstruct); return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ error: { if (reconstruct) gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), reconstruct); return ret; } }
static GstVaapiEncoderStatus gst_vaapi_encoder_vp8_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; reconstruct = gst_vaapi_encoder_create_surface (base_encoder); g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); if (!ensure_sequence (encoder, picture)) goto error; if (!ensure_misc_params (encoder, picture)) goto error; if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) goto error; if (!ensure_quantization_table (encoder, picture)) goto error; if (!gst_vaapi_enc_picture_encode (picture)) goto error; if (reconstruct) { if (picture->type == GST_VAAPI_PICTURE_TYPE_I) clear_references (encoder); push_reference (encoder, reconstruct); } return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ error: { if (reconstruct) gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), reconstruct); return ret; } }