Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#175 closed defect (fixed)

Bug Report about mp4 module

Reported by: Xietong LU Owned by: somebody
Priority: minor Milestone:
Component: nginx-core Version: 1.3.x
Keywords: Cc:
uname -a:
nginx -V: nginx -V

Description

The ngx_http_mp4_update_stsc_atom function has some bug.

Change History (12)

comment:1 by maxim, 12 years ago

Probably. But could you please provide more information about the bug you discovered?

in reply to:  1 comment:2 by Xietong LU, 12 years ago

Replying to maxim:

Probably. But could you please provide more information about the bug you discovered?

I think there are two bugs and I just found out how to fix one of them.
In line 2491, whenever trak->chunk_samples is true, the variable entries should increase 1.
So entries++; should be added.
I didn't test it yet because I can't compile nginx with my computer.

Last edited 12 years ago by Xietong LU (previous) (diff)

comment:3 by Maxim Dounin, 12 years ago

Could you please instead provide a description of the problem you are seeing, and steps to reproduce it? I think you're right and something like this

--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -2500,6 +2500,8 @@ found:
 
     if (trak->chunk_samples) {
 
+        entries++;
+
         first = &trak->stsc_chunk_entry;
         ngx_mp4_set_32value(first->chunk, 1);
         ngx_mp4_set_32value(first->samples, samples - trak->chunk_samples);

is indeed needed to correctly handle non-keyframe seeks, but it would be good to see the actual problem before trying to fix it.

in reply to:  3 comment:4 by Xietong LU, 12 years ago

Replying to Maxim Dounin:

Could you please instead provide a description of the problem you are seeing, and steps to reproduce it? I think you're right and something like this

--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -2500,6 +2500,8 @@ found:
 
     if (trak->chunk_samples) {
 
+        entries++;
+
         first = &trak->stsc_chunk_entry;
         ngx_mp4_set_32value(first->chunk, 1);
         ngx_mp4_set_32value(first->samples, samples - trak->chunk_samples);

is indeed needed to correctly handle non-keyframe seeks, but it would be good to see the actual problem before trying to fix it.

I use an mp4 file for testing. Inside the sample to chunk box, the original entries are

Entry{firstChunk=1, samplePerChunk=13, sampleDescriptionIndex=1}
Entry{firstChunk=2, samplePerChunk=12, sampleDescriptionIndex=1}
Entry{firstChunk=167, samplePerChunk=9, sampleDescriptionIndex=1}

Then I use wget with different start time to download the regenerated mp4 files. When the start time is 0.1, where the start sample is 2nd one, the new entries are

Entry{firstChunk=1, samplePerChunk=11, sampleDescriptionIndex=1}
Entry{firstChunk=2, samplePerChunk=13, sampleDescriptionIndex=1}
Entry{firstChunk=2, samplePerChunk=12, sampleDescriptionIndex=1}

(I'm using the mp4 parser from the website: http://code.google.com/p/mp4parser/)
Other information is as follow.
type: stsc
size: 64
version: 0
entries: 3

You can find 2 bugs here.

  1. Entry{firstChunk=167, samplePerChunk=9, sampleDescriptionIndex=1} is missing. Actually, this entry is inside the file from the size of this box, but the number of entries is 3. Then the parser didn't show it out.
  2. Entry{firstChunk=2, samplePerChunk=13, sampleDescriptionIndex=1} should be deleted. It happened when the start sample is located in the last chunk specified by an entry. For example, when the start sample are from 1983 - 1993, similar problem will happen again.

My English is poor and I can't express it very clearly.

comment:5 by Xietong LU, 12 years ago

I think the second problem can be solved by this way

+       if (trak->chunk_samples&& (start_sample/samples == next_chunk - chunk)){
+	   ngx_mp4_set_32value(entry->samples, samples - trak->chunk_samples);
+	}
        else if (trak->chunk_samples) {

		entries++; 
		...

comment:6 by Maxim Dounin, 12 years ago

Could you please provide the mp4 file in question for testing?

in reply to:  6 comment:7 by Xietong LU, 12 years ago

Replying to Maxim Dounin:

Could you please provide the mp4 file in question for testing?

The original file.
https://docs.google.com/open?id=0B3Wt0yFGIKL1M21fTDEtM2lUR1k
The output file.
https://docs.google.com/open?id=0B3Wt0yFGIKL1WE16Sm5hb19oX0k

comment:8 by Maxim Dounin, 12 years ago

Ok, thanks. The following patch seems to resolve both issues:

--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -2498,7 +2498,13 @@ found:
 
     ngx_mp4_set_32value(entry->chunk, 1);
 
-    if (trak->chunk_samples) {
+    if (trak->chunk_samples && next_chunk - trak->start_chunk == 2) {
+
+        /* last chunk in the entry */
+
+        ngx_mp4_set_32value(entry->samples, samples - trak->chunk_samples);
+
+    } else if (trak->chunk_samples) {
 
         first = &trak->stsc_chunk_entry;
         ngx_mp4_set_32value(first->chunk, 1);
@@ -2514,6 +2520,7 @@ found:
 
         ngx_mp4_set_32value(entry->chunk, 2);
 
+        entries++;
         atom_size += sizeof(ngx_mp4_stsc_entry_t);
     }
 

Is it looks ok for you?

in reply to:  8 comment:9 by Xietong LU, 12 years ago

Replying to Maxim Dounin:

Ok, thanks. The following patch seems to resolve both issues:

--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -2498,7 +2498,13 @@ found:
 
     ngx_mp4_set_32value(entry->chunk, 1);
 
-    if (trak->chunk_samples) {
+    if (trak->chunk_samples && next_chunk - trak->start_chunk == 2) {
+
+        /* last chunk in the entry */
+
+        ngx_mp4_set_32value(entry->samples, samples - trak->chunk_samples);
+
+    } else if (trak->chunk_samples) {
 
         first = &trak->stsc_chunk_entry;
         ngx_mp4_set_32value(first->chunk, 1);
@@ -2514,6 +2520,7 @@ found:
 
         ngx_mp4_set_32value(entry->chunk, 2);
 
+        entries++;
         atom_size += sizeof(ngx_mp4_stsc_entry_t);
     }
 

Is it looks ok for you?

yes. It looks ok.

comment:10 by Maxim Dounin, 12 years ago

In [4688/nginx]:

(The changeset message doesn't reference this ticket)

comment:11 by Maxim Dounin, 12 years ago

Resolution: fixed
Status: newclosed

Fix committed, thanks.

comment:12 by Maxim Dounin, 12 years ago

In [4728/nginx]:

(The changeset message doesn't reference this ticket)

Note: See TracTickets for help on using tickets.