Ticket #420: SoundFragmentsAfterSeeking.txt

File SoundFragmentsAfterSeeking.txt, 3.5 KB (added by kaptnole, 5 years ago)

Sound bug demonstrating sourcecode

Line 
1
2Hi, while trying to use FFmpeg libs as a developer I found the following:
3
4When decoding sound from some compressed audio formats and doing a seek, the first decoded packet after seeking is buggy.
5
6I had this with some mp4 files with aac audio codec and some wmv files with wma audio codec.
7Looks like some leftovers from internal buffers - but I am using 'avcodec_flush_buffers'!
8That of course leads to nasty sound noise/clicks.
9
10See sourcecode below.
11Basically it shows the first few bytes of the first decoded sound packet then seeks back and shows the first packets decoding again.
12If you use it with some wmv or mp4 file with sound you should see see effect that both outputs at 0 are different but should be equal.
13Just make sure the sound is not only silence at the first 10 packets.
14
15Or am I missing some other flush...whatever function here?
16
17I am developing under windows using the actual ffmpeg git version.
18Confirmed for 32 and 64 bit version, self compiled and downloaded autobuilds.
19
20
21
22// *** Sourcecode from here ***
23
24AVFormatContext *pFormatCtx = NULL;
25AVPacket        packet;
26AVStream        *pSoundStream = NULL;
27AVCodec         *pSoundCodec = NULL;
28unsigned char *pSoundDecodeBuff;
29const int SoundDecodeBuffSize = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
30
31// Decode next sound packet, print some data and return timestamp
32int64_t DecodeSoundPacket() {
33    while (av_read_frame(pFormatCtx, &packet) >= 0) {
34        if (packet.stream_index == pSoundStream->index) {
35            int nBuff = SoundDecodeBuffSize;
36            int used = avcodec_decode_audio3(pSoundStream->codec, (int16_t*)pSoundDecodeBuff, &nBuff, &packet);
37            if (used != packet.size) printf("Problem while decoding!\n");   // This also indicates multi frame packets
38            av_free_packet(&packet);
39            break;
40        }
41        av_free_packet(&packet);
42    }
43    printf("Packet at %.2f:", (float)packet.dts * pSoundStream->time_base.num / pSoundStream->time_base.den);
44    for (int i = 0; i < 20; i++) printf(" %.2x", (int)pSoundDecodeBuff[i]);
45    printf("\n");
46    return packet.dts;
47}
48
49int main(int argc, char* argv[]) {
50    // Open media file
51    av_register_all();
52    if(av_open_input_file(&pFormatCtx, "D:\\Projekte\\VideoTest\\VideoTest_1280x720_29p_h264_Audio48k.mp4", NULL, 0, NULL) != 0) return -1;
53    if(av_find_stream_info(pFormatCtx) < 0) return -1;
54
55    // Find the first sound stream
56    for(int i = 0; i < (int)pFormatCtx->nb_streams; i++)
57        if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
58            pSoundStream = pFormatCtx->streams[i];
59            break;
60        }
61    if(pSoundStream == NULL) return -1;
62
63    // Open the decoder for the sound stream
64    pSoundCodec = avcodec_find_decoder(pSoundStream->codec->codec_id);
65    if (pSoundCodec==NULL) return -1;
66    if (avcodec_open(pSoundStream->codec, pSoundCodec) < 0) return -1;
67    pSoundDecodeBuff = (unsigned char*)av_malloc(SoundDecodeBuffSize);
68
69    // Decode first packet and some others
70    int64_t SeekTo = DecodeSoundPacket();
71    for (int i = 0; i < 10; i++) DecodeSoundPacket();
72
73    // Seek back
74    printf("\nSeeking now...\n\n");
75    av_seek_frame(pFormatCtx, pSoundStream->index, SeekTo, AVSEEK_FLAG_BACKWARD);
76    avcodec_flush_buffers(pSoundStream->codec);
77
78    // Enable this and the bug is gone
79    //avcodec_close(pSoundStream->codec);           
80    //avcodec_open(pSoundStream->codec, pSoundCodec);
81
82    // Decode first packet again
83    DecodeSoundPacket();
84
85    // No cleanup - I am soooo dirty
86}