struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context, AVStream *stream, unsigned int packet_queue_size, unsigned int frame_queue_size) { bool success; assert(codec_context != NULL); assert(stream != NULL); struct ff_decoder *decoder = av_mallocz(sizeof(struct ff_decoder)); if (decoder == NULL) goto fail; decoder->codec = codec_context; decoder->codec->opaque = decoder; decoder->stream = stream; decoder->abort = false; decoder->finished = false; decoder->packet_queue_size = packet_queue_size; if (!packet_queue_init(&decoder->packet_queue)) goto fail1; decoder->timer_next_wake = (double)av_gettime() / 1000000.0; decoder->previous_pts_diff = 40e-3; decoder->current_pts_time = av_gettime(); decoder->start_pts = 0; decoder->predicted_pts = 0; decoder->first_frame = true; success = ff_timer_init(&decoder->refresh_timer, ff_decoder_refresh, decoder); if (!success) goto fail2; success = ff_circular_queue_init(&decoder->frame_queue, sizeof(struct ff_frame), frame_queue_size); if (!success) goto fail3; return decoder; fail3: ff_timer_free(&decoder->refresh_timer); fail2: packet_queue_free(&decoder->packet_queue); fail1: av_free(decoder); fail: return NULL; }
void ff_decoder_free(struct ff_decoder *decoder) { void *decoder_thread_result; int i; assert(decoder != NULL); decoder->abort = true; ff_circular_queue_abort(&decoder->frame_queue); packet_queue_abort(&decoder->packet_queue); ff_timer_free(&decoder->refresh_timer); pthread_join(decoder->decoder_thread, &decoder_thread_result); for (i = 0; i < decoder->frame_queue.capacity; i++) { void *item = decoder->frame_queue.slots[i]; struct ff_frame *frame = (struct ff_frame *)item; ff_callbacks_frame_free(frame, decoder->callbacks); if (frame != NULL) { if (frame->frame != NULL) av_frame_unref(frame->frame); if (frame->clock != NULL) ff_clock_release(&frame->clock); av_free(frame); } } packet_queue_free(&decoder->packet_queue); ff_circular_queue_free(&decoder->frame_queue); avcodec_close(decoder->codec); av_free(decoder); }
void destroy_server(struct server *srv) { conn_queue_free(srv->cq_conn); packet_queue_free(srv->pq_client); close_user_chan(srv->ctl_fd); }