Http Streaming от ffmpeg, как получить упорядоченный пакет? - PullRequest
0 голосов
/ 02 сентября 2011

Я пытаюсь создать http потоковую программу.
Поэтому я следую этому коду на этом .
Однако когда я декодирую, декодируется только один кадр.
Я думаю, что мне нужна функция обратного вызова.
Вы знаете, как сделать функцию обратного вызова?
Я знаю, что функция обратного вызова пакета asf похожа на int read_data(void *opaque, char *buf, int buf_size)

Но другие форматы (mp3, ogg, aac, ..) не работают ..

Пожалуйста, помогите мне.

Любой совет или комментарий очень ценятся.

#include <stdio.h>
#include <stdlib.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>

int main(int argc, char **argv)
{
        static AVInputFormat *file_iformat;
        static AVFormatContext *pFormatCtx;
        AVFormatParameters params;

        AVCodecContext *pCodecCtx;
        AVCodec *pCodec;

        const char url[] = "http://listen.radionomy.com/feelingfloyd";

        avcodec_register_all();
        avdevice_register_all();
        av_register_all();

        av_log_set_level(AV_LOG_VERBOSE);

        file_iformat = av_find_input_format("mp3"); /* mp3 demuxer */
        if (!file_iformat)
        {
                fprintf(stderr, "Unknown input format: %s\n", &url[0]);
                exit(1);
        }

        //file_iformat->flags |= AVFMT_NOFILE; /* ??? */
        params.prealloced_context = 0;

        if (av_open_input_file(&pFormatCtx, &url[0], file_iformat, 0, &params) != 0)
        {
                fprintf(stderr, "err 1\n");
                exit(2);
        }

        /* poulates AVFormatContex structure */
        if (av_find_stream_info(pFormatCtx) < 0)
        {
                fprintf(stderr, "err 2\n");
        }

        /* sanity check (1 stream) */
        if (pFormatCtx->nb_streams != 1 &&
                        pFormatCtx->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
        {
                fprintf(stderr, "err 3\n");
        }

        pCodecCtx = pFormatCtx->streams[0]->codec;

        /* find decoder for input audio stream */
        pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
        if (pCodec == NULL)
        {
                fprintf(stderr, "err 4: unsupported codec\n");
        }

        if (pCodec->capabilities & CODEC_CAP_TRUNCATED)
                pCodecCtx->flags |= CODEC_FLAG_TRUNCATED;

        if (avcodec_open(pCodecCtx, pCodec) < 0)
        {
                fprintf(stderr, "err 5\n");
        }

        {
                uint8_t *pAudioBuffer;
                AVPacket pkt;

                int ret;
                int data_size = 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE;

                av_init_packet(&pkt);
                //pkt.data=NULL;
                //pkt.size=0;
                //pkt.stream_index = 0;

                pAudioBuffer = av_malloc(data_size * sizeof(int16_t));

                while (av_read_frame(pFormatCtx, &pkt) == 0) {
                        //data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
                        ret = avcodec_decode_audio3(pFormatCtx->streams[pkt.stream_index]->codec,
                                        (int16_t *)pAudioBuffer, &data_size, &pkt);

                        /* got an error (-32) here */
                        if (ret < 0) {
                                av_strerror(ret, (char *)pAudioBuffer, data_size);
                                fprintf(stderr, "err 6 (%s)\n", pAudioBuffer);
                                break;
                        }

                        printf("size=%d, stream_index=%d |ret=%d data_size=%d\n",
                                        pkt.size, pkt.stream_index, ret, data_size);
                        av_free_packet(&pkt);
                }

                av_free(pAudioBuffer);
        }

        avcodec_close(pCodecCtx);
        av_close_input_file(pFormatCtx);

        return 0;
}

1 Ответ

0 голосов
/ 10 сентября 2011

Я выяснил эту проблему с помощью av_open_input_file.
У меня возникла эта проблема, когда я создал приложение для iphone, которое воспроизводит потоковую передачу по HTTP.И приведенный выше код не сработал.Проигрывается только часть аудио кадра.это также означает, что существует так много буферизации.
Однако, после использования функции обратного вызова аудио iphone и большого аудио буфера, он работает нормально.
Те, кому интересно окончательный код, посылают мне сообщение.

...