lavc/mediacodecdec_h264: switch to new BSF API

This commit is contained in:
Matthieu Bouron 2016-05-26 14:52:01 +02:00
parent e0df56f25d
commit 15432a903e
1 changed files with 38 additions and 27 deletions

View File

@ -23,6 +23,7 @@
#include <stdint.h>
#include <string.h>
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/fifo.h"
#include "libavutil/opt.h"
@ -41,13 +42,11 @@ typedef struct MediaCodecH264DecContext {
MediaCodecDecContext ctx;
AVBitStreamFilterContext *bsf;
AVBSFContext *bsf;
AVFifoBuffer *fifo;
AVPacket input_ref;
AVPacket filtered_pkt;
uint8_t *filtered_data;
} MediaCodecH264DecContext;
@ -157,7 +156,8 @@ static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
av_fifo_free(s->fifo);
av_bitstream_filter_close(s->bsf);
av_bsf_free(&s->bsf);
av_packet_unref(&s->filtered_pkt);
return 0;
}
@ -211,12 +211,23 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
goto done;
}
s->bsf = av_bitstream_filter_init("h264_mp4toannexb");
if (!s->bsf) {
ret = AVERROR(ENOMEM);
const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");
if(!bsf) {
ret = AVERROR_BSF_NOT_FOUND;
goto done;
}
if ((ret = av_bsf_alloc(bsf, &s->bsf))) {
goto done;
}
if (((ret = avcodec_parameters_from_context(s->bsf->par_in, avctx)) < 0) ||
((ret = av_bsf_init(s->bsf)) < 0)) {
goto done;
}
av_init_packet(&s->filtered_pkt);
done:
if (format) {
ff_AMediaFormat_delete(format);
@ -265,7 +276,9 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
while (!*got_frame) {
/* prepare the input data -- convert to Annex B if needed */
if (s->filtered_pkt.size <= 0) {
int size;
AVPacket input_pkt = { 0 };
av_packet_unref(&s->filtered_pkt);
/* no more data */
if (av_fifo_size(s->fifo) < sizeof(AVPacket)) {
@ -273,22 +286,24 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, avpkt);
}
if (s->filtered_data != s->input_ref.data)
av_freep(&s->filtered_data);
s->filtered_data = NULL;
av_packet_unref(&s->input_ref);
av_fifo_generic_read(s->fifo, &input_pkt, sizeof(input_pkt), NULL);
av_fifo_generic_read(s->fifo, &s->input_ref, sizeof(s->input_ref), NULL);
ret = av_bitstream_filter_filter(s->bsf, avctx, NULL,
&s->filtered_data, &size,
s->input_ref.data, s->input_ref.size, 0);
ret = av_bsf_send_packet(s->bsf, &input_pkt);
if (ret < 0) {
s->filtered_data = s->input_ref.data;
size = s->input_ref.size;
return ret;
}
ret = av_bsf_receive_packet(s->bsf, &s->filtered_pkt);
if (ret == AVERROR(EAGAIN)) {
goto done;
}
/* h264_mp4toannexb is used here and does not requires flushing */
av_assert0(ret != AVERROR_EOF);
if (ret < 0) {
return ret;
}
s->filtered_pkt = s->input_ref;
s->filtered_pkt.data = s->filtered_data;
s->filtered_pkt.size = size;
}
ret = mediacodec_process_data(avctx, frame, got_frame, &s->filtered_pkt);
@ -298,7 +313,7 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
s->filtered_pkt.size -= ret;
s->filtered_pkt.data += ret;
}
done:
return avpkt->size;
}
@ -313,11 +328,7 @@ static void mediacodec_decode_flush(AVCodecContext *avctx)
}
av_fifo_reset(s->fifo);
av_packet_unref(&s->input_ref);
av_init_packet(&s->filtered_pkt);
s->filtered_pkt.data = NULL;
s->filtered_pkt.size = 0;
av_packet_unref(&s->filtered_pkt);
ff_mediacodec_dec_flush(avctx, &s->ctx);
}