1

I'm trying to decode h.264 streaming with ffmpeg(latest version) on Android NDK.

I succeeded to get a decoded frame. But, an aquired image is very dirty even if low latency flag is disabled.

If I want to give priority to quality over decoding speed, which flags should I specify?

bool initCodec(bool low_latency)
{
    av_register_all();

    codec = avcodec_find_decoder(AV_CODEC_ID_H264);
    if(!codec) return false;

    context = avcodec_alloc_context3(codec);
    if(!context) return false;

    if(codec->capabilities & CODEC_CAP_TRUNCATED) context->flags |= CODEC_FLAG_TRUNCATED;
    if(low_latency == true) context->flags |= CODEC_FLAG_LOW_DELAY;

    frame = av_frame_alloc();

    int res = avcodec_open2(context, codec, NULL);
    if (res < 0) {
        qDebug() << "Coundn't open codec :" << res;
        return false;
    }

    av_init_packet(&avpkt);
    return true;
}

void sendBytes(unsigned char *buf, int buflen)
{
    avpkt.size = buflen;
    avpkt.data = buf;

    int got_frame, len;
    while (avpkt.size > 0) {
        len = avcodec_decode_video2(context, frame, &got_frame, &avpkt);
        if (len < 0) {
            qDebug() << "Error while decoding : " << len;
            break;
        }
        if (got_frame) {
            onGotFrame(frame);
        }
        avpkt.size -= len;
        avpkt.data += len;
    }
}

Decoded image sample

Ex: I heard that it made a problem while compiling the library. So I write a compile option here(I built it on OpenSUSE Linux).

#!/bin/bash
NDK=/home/ndk
SYSROOT=$NDK/platforms/android-9/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function build_one
{
./configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-avdevice \
--disable-doc \
--disable-symver \
--disable-encoders \
--disable-decoders \
--enable-decoder=h264 \
--enable-decoder=aac \
--disable-protocols \
--disable-demuxers \
--disable-muxers \
--disable-filters \
--disable-network \
--disable-parsers \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-asm --enable-yasm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -marm -march=armv7-a -mfloat-abi=softfp -mfpu=neon" \
--extra-ldflags="-Wl,--fix-cortex-a8" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
CPU=armv7-a
PREFIX=$(pwd)/android/$CPU
build_on
Tank2005
  • 899
  • 1
  • 14
  • 32

1 Answers1

0

See this response, you need a parser. Here's an example of how the API works. You basically call av_parser_parse2() in a loop with your input data, and it will spit out frame-delimited data chunks, which you can then feed into avcodec_decode_video2().

Community
  • 1
  • 1
Ronald S. Bultje
  • 10,828
  • 26
  • 47
  • I changed the build option to "--enable-parsers" and append parse functions. Result image becomes fine. Thanks a lot. – Tank2005 Jan 20 '16 at 05:31